summaryrefslogtreecommitdiffstats
path: root/core/java
diff options
context:
space:
mode:
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();
}
}
}