summaryrefslogtreecommitdiffstats
path: root/core/java
diff options
context:
space:
mode:
authorVasu Nori <vnori@google.com>2010-02-18 13:35:42 -0800
committerVasu Nori <vnori@google.com>2010-02-18 14:49:45 -0800
commite8de28415b4362824a52c180adf10dd882d12eaf (patch)
tree58762de7f639a841a955be6eedfd9d33e3c3eaa9 /core/java
parent6c2cc0d48ac51181d31017fbf8d735c9f91a1539 (diff)
downloadframeworks_base-e8de28415b4362824a52c180adf10dd882d12eaf.zip
frameworks_base-e8de28415b4362824a52c180adf10dd882d12eaf.tar.gz
frameworks_base-e8de28415b4362824a52c180adf10dd882d12eaf.tar.bz2
bug fix for 2419869. also included 2 unittests.
bug fix for 2419869 is the following 1. only one object can use the prepared statement object (SQLiteCompiledSql in SQLIteProgram) 2. if two objects are requesting to use it, then create a new prepared statement object for exclusive use by the newcomer and let it be be finalized by the newcomer. 3. add mInUse flag to SQLiteCompiledSql - to be set when SQLiteProgram requests it and to be released when that SQLiteProgram is done with it a couple more changes included are 1. unitests to simulate bug # 2419869 (and the fix's repair to it) 2. better logging in SQLiteCloseable when it prints log messages
Diffstat (limited to 'core/java')
-rw-r--r--core/java/android/database/sqlite/SQLiteCompiledSql.java15
-rw-r--r--core/java/android/database/sqlite/SQLiteProgram.java25
2 files changed, 37 insertions, 3 deletions
diff --git a/core/java/android/database/sqlite/SQLiteCompiledSql.java b/core/java/android/database/sqlite/SQLiteCompiledSql.java
index 79527b4..eb85822 100644
--- a/core/java/android/database/sqlite/SQLiteCompiledSql.java
+++ b/core/java/android/database/sqlite/SQLiteCompiledSql.java
@@ -44,6 +44,9 @@ import android.util.Log;
*/
/* package */ int nStatement = 0;
+ /** when in cache and is in use, this member is set */
+ private boolean mInUse = false;
+
/* package */ SQLiteCompiledSql(SQLiteDatabase db, String sql) {
mDatabase = db;
this.nHandle = db.mNativeHandle;
@@ -92,6 +95,18 @@ import android.util.Log;
}
}
+ /* package */ synchronized boolean isInUse() {
+ return mInUse;
+ }
+
+ /* package */ synchronized void acquire() {
+ mInUse = true;
+ }
+
+ /* package */ synchronized void release() {
+ mInUse = false;
+ }
+
/**
* Make sure that the native resource is cleaned up.
*/
diff --git a/core/java/android/database/sqlite/SQLiteProgram.java b/core/java/android/database/sqlite/SQLiteProgram.java
index 2d0aa39..2bb2f5d 100644
--- a/core/java/android/database/sqlite/SQLiteProgram.java
+++ b/core/java/android/database/sqlite/SQLiteProgram.java
@@ -58,32 +58,51 @@ public abstract class SQLiteProgram extends SQLiteClosable {
// add it to the cache of compiled-sqls
db.addToCompiledQueries(sql, mCompiledSql);
+ mCompiledSql.acquire();
+ } else {
+ // it is already in compiled-sql cache.
+ if (mCompiledSql.isInUse()) {
+ // but the CompiledSql in cache is in use by some other SQLiteProgram object.
+ // we can't have two different SQLiteProgam objects can't share the same
+ // CompiledSql object. create a new one.
+ // finalize it when I am done with it in "this" object.
+ mCompiledSql = new SQLiteCompiledSql(db, sql);
+ } else {
+ // the CompiledSql in cache is NOT in use by any other SQLiteProgram object.
+ // it is safe to give it to this SQLIteProgram Object.
+ mCompiledSql.acquire();
+ }
}
nStatement = mCompiledSql.nStatement;
}
@Override
protected void onAllReferencesReleased() {
- releaseCompiledSqlIfInCache();
+ releaseCompiledSqlIfNotInCache();
mDatabase.releaseReference();
mDatabase.removeSQLiteClosable(this);
}
@Override
protected void onAllReferencesReleasedFromContainer() {
- releaseCompiledSqlIfInCache();
+ releaseCompiledSqlIfNotInCache();
mDatabase.releaseReference();
}
- private void releaseCompiledSqlIfInCache() {
+ private void releaseCompiledSqlIfNotInCache() {
if (mCompiledSql == null) {
return;
}
synchronized(mDatabase.mCompiledQueries) {
if (!mDatabase.mCompiledQueries.containsValue(mCompiledSql)) {
+ // it is NOT in compiled-sql cache. i.e., responsibility of
+ // release this statement is on me.
mCompiledSql.releaseSqlStatement();
mCompiledSql = null; // so that GC doesn't call finalize() on it
nStatement = 0;
+ } else {
+ // it is in compiled-sql cache. reset its CompiledSql#mInUse flag
+ mCompiledSql.release();
}
}
}