Merge "sometimes database lock is not held before compiling a statement"
This commit is contained in:
@@ -78,20 +78,13 @@ import android.util.Log;
|
||||
* existing compiled SQL program already around
|
||||
*/
|
||||
private void compile(String sql, boolean forceCompilation) {
|
||||
if (!mDatabase.isOpen()) {
|
||||
throw new IllegalStateException("database " + mDatabase.getPath() + " already closed");
|
||||
}
|
||||
mDatabase.verifyLockOwner();
|
||||
// Only compile if we don't have a valid statement already or the caller has
|
||||
// explicitly requested a recompile.
|
||||
if (forceCompilation) {
|
||||
mDatabase.lock();
|
||||
try {
|
||||
// Note that the native_compile() takes care of destroying any previously
|
||||
// existing programs before it compiles.
|
||||
native_compile(sql);
|
||||
} finally {
|
||||
mDatabase.unlock();
|
||||
}
|
||||
// Note that the native_compile() takes care of destroying any previously
|
||||
// existing programs before it compiles.
|
||||
native_compile(sql);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -275,20 +275,22 @@ public class SQLiteDatabase extends SQLiteClosable {
|
||||
// if it needs to be removed to accommodate a new entry,
|
||||
// close {@link SQLiteCompiledSql} represented by this entry, if not in use
|
||||
// and then let it be removed from the Map.
|
||||
synchronized(mCompiledQueries) { // probably not necessary, but can't hurt
|
||||
if (this.size() <= mMaxSqlCacheSize) {
|
||||
// cache is not full. nothing needs to be removed
|
||||
return false;
|
||||
}
|
||||
// cache is full. eldest will be removed.
|
||||
SQLiteCompiledSql entry = eldest.getValue();
|
||||
if (!entry.isInUse()) {
|
||||
// this {@link SQLiteCompiledSql} is not in use. release it.
|
||||
entry.releaseSqlStatement();
|
||||
}
|
||||
// return true, so that this entry is removed automatically by the caller.
|
||||
return true;
|
||||
// when this is called, the caller must be trying to add a just-compiled stmt
|
||||
// to cache; i.e., caller should already have acquired database lock AND
|
||||
// the lock on mCompiledQueries. do as assert of these two 2 facts.
|
||||
verifyLockOwner();
|
||||
if (this.size() <= mMaxSqlCacheSize) {
|
||||
// cache is not full. nothing needs to be removed
|
||||
return false;
|
||||
}
|
||||
// cache is full. eldest will be removed.
|
||||
SQLiteCompiledSql entry = eldest.getValue();
|
||||
if (!entry.isInUse()) {
|
||||
// this {@link SQLiteCompiledSql} is not in use. release it.
|
||||
entry.releaseSqlStatement();
|
||||
}
|
||||
// return true, so that this entry is removed automatically by the caller.
|
||||
return true;
|
||||
}
|
||||
};
|
||||
/**
|
||||
@@ -1979,6 +1981,15 @@ public class SQLiteDatabase extends SQLiteClosable {
|
||||
}
|
||||
}
|
||||
|
||||
/* package */ void verifyLockOwner() {
|
||||
if (!isOpen()) {
|
||||
throw new IllegalStateException("database " + getPath() + " already closed");
|
||||
}
|
||||
if (!isDbLockedByCurrentThread() && mLockingEnabled) {
|
||||
throw new IllegalStateException("Don't have database lock!");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* ============================================================================
|
||||
*
|
||||
|
||||
@@ -39,9 +39,11 @@ public class SQLiteDirectCursorDriver implements SQLiteCursorDriver {
|
||||
|
||||
public Cursor query(CursorFactory factory, String[] selectionArgs) {
|
||||
// Compile the query
|
||||
SQLiteQuery query = new SQLiteQuery(mDatabase, mSql, 0, selectionArgs);
|
||||
SQLiteQuery query = null;
|
||||
|
||||
try {
|
||||
mDatabase.lock();
|
||||
query = new SQLiteQuery(mDatabase, mSql, 0, selectionArgs);
|
||||
// Arg binding
|
||||
int numArgs = selectionArgs == null ? 0 : selectionArgs.length;
|
||||
for (int i = 0; i < numArgs; i++) {
|
||||
@@ -61,6 +63,7 @@ public class SQLiteDirectCursorDriver implements SQLiteCursorDriver {
|
||||
} finally {
|
||||
// Make sure this object is cleaned up if something happens
|
||||
if (query != null) query.close();
|
||||
mDatabase.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user