diff options
| author | Fred Quintana <fredq@google.com> | 2010-11-16 17:36:43 -0800 |
|---|---|---|
| committer | Android (Google) Code Review <android-gerrit@google.com> | 2010-11-16 17:36:43 -0800 |
| commit | 2978e5ad46ff3e124ae7d01016cefddacbc03ef4 (patch) | |
| tree | a55828ad2e2285fdf2510af278855d5a7b1d08dc /core | |
| parent | aaf12770b8a856a32739bd3ae76fd3eb870e0132 (diff) | |
| parent | 866647f9b4d78ea5791d7480a459d93629afbf97 (diff) | |
| download | frameworks_base-2978e5ad46ff3e124ae7d01016cefddacbc03ef4.zip frameworks_base-2978e5ad46ff3e124ae7d01016cefddacbc03ef4.tar.gz frameworks_base-2978e5ad46ff3e124ae7d01016cefddacbc03ef4.tar.bz2 | |
Merge "handle a race condition where a cursor receives an inflight onChange after the cursor has been closed"
Diffstat (limited to 'core')
| -rw-r--r-- | core/java/android/content/ContentQueryMap.java | 26 |
1 files changed, 17 insertions, 9 deletions
diff --git a/core/java/android/content/ContentQueryMap.java b/core/java/android/content/ContentQueryMap.java index c955094..8aeaa8f 100644 --- a/core/java/android/content/ContentQueryMap.java +++ b/core/java/android/content/ContentQueryMap.java @@ -33,7 +33,7 @@ import java.util.Observable; * The cursor data is accessed by row key and column name via getValue(). */ public class ContentQueryMap extends Observable { - private Cursor mCursor; + private volatile Cursor mCursor; private String[] mColumnNames; private int mKeyColumn; @@ -71,7 +71,7 @@ public class ContentQueryMap extends Observable { // ContentProvider then read it once into the cache. Otherwise the cache will be filled // automatically. if (!keepUpdated) { - readCursorIntoCache(); + readCursorIntoCache(cursor); } } @@ -128,27 +128,35 @@ public class ContentQueryMap extends Observable { /** Requeries the cursor and reads the contents into the cache */ public void requery() { + final Cursor cursor = mCursor; + if (cursor == null) { + // If mCursor is null then it means there was a requery() in flight + // while another thread called close(), which nulls out mCursor. + // If this happens ignore the requery() since we are closed anyways. + return; + } mDirty = false; - if (!mCursor.requery()) { - throw new IllegalStateException("trying to requery an already closed cursor"); + if (!cursor.requery()) { + // again, don't do anything if the cursor is already closed + return; } - readCursorIntoCache(); + readCursorIntoCache(cursor); setChanged(); notifyObservers(); } - private synchronized void readCursorIntoCache() { + private synchronized void readCursorIntoCache(Cursor cursor) { // Make a new map so old values returned by getRows() are undisturbed. int capacity = mValues != null ? mValues.size() : 0; mValues = new HashMap<String, ContentValues>(capacity); - while (mCursor.moveToNext()) { + while (cursor.moveToNext()) { ContentValues values = new ContentValues(); for (int i = 0; i < mColumnNames.length; i++) { if (i != mKeyColumn) { - values.put(mColumnNames[i], mCursor.getString(i)); + values.put(mColumnNames[i], cursor.getString(i)); } } - mValues.put(mCursor.getString(mKeyColumn), values); + mValues.put(cursor.getString(mKeyColumn), values); } } |
