summaryrefslogtreecommitdiffstats
path: root/core/jni
diff options
context:
space:
mode:
authorJeff Brown <jeffbrown@google.com>2012-01-25 19:37:13 -0800
committerJeff Brown <jeffbrown@google.com>2012-01-27 17:33:21 -0800
commit75ea64fc54f328d37b115cfb1ded1e45c30380ed (patch)
tree4254a5d2d0662de8b606b38fea6987da17c130e3 /core/jni
parentebc016c01ea9d5707287cfc19ccc59b21a486c00 (diff)
downloadframeworks_base-75ea64fc54f328d37b115cfb1ded1e45c30380ed.zip
frameworks_base-75ea64fc54f328d37b115cfb1ded1e45c30380ed.tar.gz
frameworks_base-75ea64fc54f328d37b115cfb1ded1e45c30380ed.tar.bz2
Implement a cancelation mechanism for queries.
Added new API to enable cancelation of SQLite and content provider queries by means of a CancelationSignal object. The application creates a CancelationSignal object and passes it as an argument to the query. The cancelation signal can then be used to cancel the query while it is executing. If the cancelation signal is raised before the query is executed, then it is immediately terminated. Change-Id: If2c76e9a7e56ea5e98768b6d4f225f0a1ca61c61
Diffstat (limited to 'core/jni')
-rw-r--r--core/jni/android_database_SQLiteCommon.cpp63
-rw-r--r--core/jni/android_database_SQLiteConnection.cpp32
2 files changed, 64 insertions, 31 deletions
diff --git a/core/jni/android_database_SQLiteCommon.cpp b/core/jni/android_database_SQLiteCommon.cpp
index a94b9d2..3484467 100644
--- a/core/jni/android_database_SQLiteCommon.cpp
+++ b/core/jni/android_database_SQLiteCommon.cpp
@@ -68,50 +68,53 @@ void throw_sqlite3_exception(JNIEnv* env, int errcode,
exceptionClass = "android/database/sqlite/SQLiteDatabaseCorruptException";
break;
case SQLITE_CONSTRAINT:
- exceptionClass = "android/database/sqlite/SQLiteConstraintException";
- break;
+ exceptionClass = "android/database/sqlite/SQLiteConstraintException";
+ break;
case SQLITE_ABORT:
- exceptionClass = "android/database/sqlite/SQLiteAbortException";
- break;
+ exceptionClass = "android/database/sqlite/SQLiteAbortException";
+ break;
case SQLITE_DONE:
- exceptionClass = "android/database/sqlite/SQLiteDoneException";
- break;
+ exceptionClass = "android/database/sqlite/SQLiteDoneException";
+ break;
case SQLITE_FULL:
- exceptionClass = "android/database/sqlite/SQLiteFullException";
- break;
+ exceptionClass = "android/database/sqlite/SQLiteFullException";
+ break;
case SQLITE_MISUSE:
- exceptionClass = "android/database/sqlite/SQLiteMisuseException";
- break;
+ exceptionClass = "android/database/sqlite/SQLiteMisuseException";
+ break;
case SQLITE_PERM:
- exceptionClass = "android/database/sqlite/SQLiteAccessPermException";
- break;
+ exceptionClass = "android/database/sqlite/SQLiteAccessPermException";
+ break;
case SQLITE_BUSY:
- exceptionClass = "android/database/sqlite/SQLiteDatabaseLockedException";
- break;
+ exceptionClass = "android/database/sqlite/SQLiteDatabaseLockedException";
+ break;
case SQLITE_LOCKED:
- exceptionClass = "android/database/sqlite/SQLiteTableLockedException";
- break;
+ exceptionClass = "android/database/sqlite/SQLiteTableLockedException";
+ break;
case SQLITE_READONLY:
- exceptionClass = "android/database/sqlite/SQLiteReadOnlyDatabaseException";
- break;
+ exceptionClass = "android/database/sqlite/SQLiteReadOnlyDatabaseException";
+ break;
case SQLITE_CANTOPEN:
- exceptionClass = "android/database/sqlite/SQLiteCantOpenDatabaseException";
- break;
+ exceptionClass = "android/database/sqlite/SQLiteCantOpenDatabaseException";
+ break;
case SQLITE_TOOBIG:
- exceptionClass = "android/database/sqlite/SQLiteBlobTooBigException";
- break;
+ exceptionClass = "android/database/sqlite/SQLiteBlobTooBigException";
+ break;
case SQLITE_RANGE:
- exceptionClass = "android/database/sqlite/SQLiteBindOrColumnIndexOutOfRangeException";
- break;
+ exceptionClass = "android/database/sqlite/SQLiteBindOrColumnIndexOutOfRangeException";
+ break;
case SQLITE_NOMEM:
- exceptionClass = "android/database/sqlite/SQLiteOutOfMemoryException";
- break;
+ exceptionClass = "android/database/sqlite/SQLiteOutOfMemoryException";
+ break;
case SQLITE_MISMATCH:
- exceptionClass = "android/database/sqlite/SQLiteDatatypeMismatchException";
- break;
+ exceptionClass = "android/database/sqlite/SQLiteDatatypeMismatchException";
+ break;
+ case SQLITE_INTERRUPT:
+ exceptionClass = "android/content/OperationCanceledException";
+ break;
default:
- exceptionClass = "android/database/sqlite/SQLiteException";
- break;
+ exceptionClass = "android/database/sqlite/SQLiteException";
+ break;
}
if (sqlite3Message != NULL && message != NULL) {
diff --git a/core/jni/android_database_SQLiteConnection.cpp b/core/jni/android_database_SQLiteConnection.cpp
index d0d53f6..e061ac3 100644
--- a/core/jni/android_database_SQLiteConnection.cpp
+++ b/core/jni/android_database_SQLiteConnection.cpp
@@ -67,8 +67,10 @@ struct SQLiteConnection {
const String8 path;
const String8 label;
+ volatile bool canceled;
+
SQLiteConnection(sqlite3* db, int openFlags, const String8& path, const String8& label) :
- db(db), openFlags(openFlags), path(path), label(label) { }
+ db(db), openFlags(openFlags), path(path), label(label), canceled(false) { }
};
// Called each time a statement begins execution, when tracing is enabled.
@@ -85,6 +87,12 @@ static void sqliteProfileCallback(void *data, const char *sql, sqlite3_uint64 tm
connection->label.string(), sql, tm * 0.000001f);
}
+// Called after each SQLite VM instruction when cancelation is enabled.
+static int sqliteProgressHandlerCallback(void* data) {
+ SQLiteConnection* connection = static_cast<SQLiteConnection*>(data);
+ return connection->canceled;
+}
+
static jint nativeOpen(JNIEnv* env, jclass clazz, jstring pathStr, jint openFlags,
jstring labelStr, jboolean enableTrace, jboolean enableProfile) {
@@ -871,6 +879,24 @@ static jint nativeGetDbLookaside(JNIEnv* env, jobject clazz, jint connectionPtr)
return cur;
}
+static void nativeCancel(JNIEnv* env, jobject clazz, jint connectionPtr) {
+ SQLiteConnection* connection = reinterpret_cast<SQLiteConnection*>(connectionPtr);
+ connection->canceled = true;
+}
+
+static void nativeResetCancel(JNIEnv* env, jobject clazz, jint connectionPtr,
+ jboolean cancelable) {
+ SQLiteConnection* connection = reinterpret_cast<SQLiteConnection*>(connectionPtr);
+ connection->canceled = false;
+
+ if (cancelable) {
+ sqlite3_progress_handler(connection->db, 4, sqliteProgressHandlerCallback,
+ connection);
+ } else {
+ sqlite3_progress_handler(connection->db, 0, NULL, NULL);
+ }
+}
+
static JNINativeMethod sMethods[] =
{
@@ -923,6 +949,10 @@ static JNINativeMethod sMethods[] =
(void*)nativeExecuteForCursorWindow },
{ "nativeGetDbLookaside", "(I)I",
(void*)nativeGetDbLookaside },
+ { "nativeCancel", "(I)V",
+ (void*)nativeCancel },
+ { "nativeResetCancel", "(IZ)V",
+ (void*)nativeResetCancel },
};
#define FIND_CLASS(var, className) \