diff options
Diffstat (limited to 'core/java')
-rw-r--r-- | core/java/android/database/sqlite/SQLiteCompiledSql.java | 15 | ||||
-rw-r--r-- | core/java/android/database/sqlite/SQLiteProgram.java | 25 |
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(); } } } |