summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorFred Quintana <fredq@google.com>2010-11-16 17:36:43 -0800
committerAndroid (Google) Code Review <android-gerrit@google.com>2010-11-16 17:36:43 -0800
commit2978e5ad46ff3e124ae7d01016cefddacbc03ef4 (patch)
treea55828ad2e2285fdf2510af278855d5a7b1d08dc /core
parentaaf12770b8a856a32739bd3ae76fd3eb870e0132 (diff)
parent866647f9b4d78ea5791d7480a459d93629afbf97 (diff)
downloadframeworks_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.java26
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);
}
}