Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5f43c29d authored by Lee Shombert's avatar Lee Shombert Committed by Rex Hoffman
Browse files

Disable WAL checkpoint from the finalizer

If SQLiteConnection.close() is called from the finalizer, disable WAL
checkpoints.  WAL checkpoint can be IO intensive and can cause the
finalizer timeout to expire.  Three things to note:

  1. The finalizer is invoked only if the application has failed to
     explicitly close the database, which is, itself, an error.  This
     change has no effect if the database is explicitly closed.

  2. Even though there is no checkpoint, the WAL file remains intact
     and no data is lost.

  3. The effect of not checkpointing is the same as if the application
     had crashed or had been killed.  Which happens all the time.

Flag: android.database.sqlite.no_checkpoint_on_finalize
Bug: 397982577
Test: atest
 * FrameworksCoreTests:android.database
 * CtsDatabaseTestCases
Change-Id: I124b3ebbf2d3378108bee04a294200b198b64299
parent bc85e45d
Loading
Loading
Loading
Loading
+7 −2
Original line number Diff line number Diff line
@@ -138,7 +138,7 @@ public final class SQLiteConnection implements CancellationSignal.OnCancelListen
    private static native long nativeOpen(String path, int openFlags, String label,
            boolean enableTrace, boolean enableProfile, int lookasideSlotSize,
            int lookasideSlotCount);
    private static native void nativeClose(long connectionPtr);
    private static native void nativeClose(long connectionPtr, boolean fast);
    private static native void nativeRegisterCustomScalarFunction(long connectionPtr,
            String name, UnaryOperator<String> function);
    private static native void nativeRegisterCustomAggregateFunction(long connectionPtr,
@@ -183,6 +183,11 @@ public final class SQLiteConnection implements CancellationSignal.OnCancelListen
    private static native long nativeChanges(long connectionPtr);
    private static native long nativeTotalChanges(long connectionPtr);

    // This method is deprecated and should be removed when it is no longer needed by the
    // robolectric tests.  It should not be called from any frameworks java code.
    @Deprecated
    private static native void nativeClose(long connectionPtr);

    private SQLiteConnection(SQLiteConnectionPool pool,
            SQLiteDatabaseConfiguration configuration,
            int connectionId, boolean primaryConnection) {
@@ -300,7 +305,7 @@ public final class SQLiteConnection implements CancellationSignal.OnCancelListen
            final int cookie = mRecentOperations.beginOperation("close", null, null);
            try {
                mPreparedStatementCache.evictAll();
                nativeClose(mConnectionPtr);
                nativeClose(mConnectionPtr, finalized && Flags.noCheckpointOnFinalize());
                mConnectionPtr = 0;
            } finally {
                mRecentOperations.endOperation(cookie);
+8 −1
Original line number Diff line number Diff line
@@ -5,7 +5,7 @@ flag {
     name: "oneway_finalizer_close_fixed"
     namespace: "system_performance"
     is_fixed_read_only: true
     description: "Make BuildCursorNative.close oneway if in the the finalizer"
     description: "Make BuildCursorNative.close oneway if in the finalizer"
     bug: "368221351"
}

@@ -26,3 +26,10 @@ flag {
     description: "Make SQLiteOpenHelper thread-safe"
     bug: "335904370"
}

flag {
     name: "no_checkpoint_on_finalize"
     namespace: "system_performance"
     description: "Do not checkpoint WAL if closing in the finalizer"
     bug: "397982577"
}
+17 −2
Original line number Diff line number Diff line
@@ -204,7 +204,7 @@ static jlong nativeOpen(JNIEnv* env, jclass clazz, jstring pathStr, jint openFla
    return reinterpret_cast<jlong>(connection);
}

static void nativeClose(JNIEnv* env, jclass clazz, jlong connectionPtr) {
static void nativeClose(JNIEnv* env, jclass clazz, jlong connectionPtr, jboolean fast) {
    SQLiteConnection* connection = reinterpret_cast<SQLiteConnection*>(connectionPtr);

    if (connection) {
@@ -212,6 +212,13 @@ static void nativeClose(JNIEnv* env, jclass clazz, jlong connectionPtr) {
        if (connection->tableQuery != nullptr) {
            sqlite3_finalize(connection->tableQuery);
        }
        if (fast) {
            // The caller requested a fast close, so do not checkpoint even if this is the last
            // connection to the database.  Note that the change is only to this connection.
            // Any other connections to the same database are unaffected.
            int _unused = 0;
            sqlite3_db_config(connection->db, SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE, 1, &_unused);
        }
        int err = sqlite3_close(connection->db);
        if (err != SQLITE_OK) {
            // This can happen if sub-objects aren't closed first.  Make sure the caller knows.
@@ -224,6 +231,12 @@ static void nativeClose(JNIEnv* env, jclass clazz, jlong connectionPtr) {
    }
}

// This method is deprecated and should be removed when it is no longer needed by the
// robolectric tests.
static void nativeClose(JNIEnv* env, jclass clazz, jlong connectionPtr) {
    nativeClose(env, clazz, connectionPtr, false);
}

static void sqliteCustomScalarFunctionCallback(sqlite3_context *context,
        int argc, sqlite3_value **argv) {
    JNIEnv* env = AndroidRuntime::getJNIEnv();
@@ -959,8 +972,10 @@ static const JNINativeMethod sMethods[] =
    /* name, signature, funcPtr */
    { "nativeOpen", "(Ljava/lang/String;ILjava/lang/String;ZZII)J",
            (void*)nativeOpen },
    { "nativeClose", "(JZ)V",
      (void*) static_cast<void(*)(JNIEnv*,jclass,jlong,jboolean)>(nativeClose) },
    { "nativeClose", "(J)V",
            (void*)nativeClose },
      (void*) static_cast<void(*)(JNIEnv*,jclass,jlong)>(nativeClose) },
    { "nativeRegisterCustomScalarFunction", "(JLjava/lang/String;Ljava/util/function/UnaryOperator;)V",
            (void*)nativeRegisterCustomScalarFunction },
    { "nativeRegisterCustomAggregateFunction", "(JLjava/lang/String;Ljava/util/function/BinaryOperator;)V",