Run post transaction tasks only after root transaction ends.

This commit is contained in:
Clark 2023-05-22 17:16:38 -04:00 committed by Nicholas
parent 61f50cfe60
commit 4a9a07a9ef
3 changed files with 50 additions and 6 deletions

View file

@ -180,4 +180,45 @@ class SQLiteDatabaseTest {
assertTrue(hasRun1.get())
assertTrue(hasRun2.get())
}
@Test
fun runPostSuccessfulTransaction_runsAfterMainTransactionInNestedTransaction() {
val hasRun1 = AtomicBoolean(false)
val hasRun2 = AtomicBoolean(false)
db.beginTransaction()
db.runPostSuccessfulTransaction {
assertFalse(hasRun1.get())
assertFalse(hasRun2.get())
hasRun1.set(true)
}
assertFalse(hasRun1.get())
assertFalse(hasRun2.get())
db.beginTransaction()
db.runPostSuccessfulTransaction {
assertTrue(hasRun1.get())
assertFalse(hasRun2.get())
hasRun2.set(true)
}
db.setTransactionSuccessful()
assertFalse(hasRun1.get())
assertFalse(hasRun2.get())
db.endTransaction()
db.setTransactionSuccessful()
assertFalse(hasRun1.get())
assertFalse(hasRun2.get())
db.endTransaction()
assertTrue(hasRun1.get())
assertTrue(hasRun2.get())
}
}

View file

@ -82,10 +82,12 @@ class InstrumentationApplicationDependencyProvider(application: Application, def
arrayOf(SignalKeyBackupServiceUrl(baseUrl, "localhost", serviceTrustStore, ConnectionSpec.CLEARTEXT)),
arrayOf(SignalStorageUrl(baseUrl, "localhost", serviceTrustStore, ConnectionSpec.CLEARTEXT)),
arrayOf(SignalCdsiUrl(baseUrl, "localhost", serviceTrustStore, ConnectionSpec.CLEARTEXT)),
emptyArray(),
emptyList(),
Optional.of(SignalServiceNetworkAccess.DNS),
Optional.empty(),
Base64.decode(BuildConfig.ZKGROUP_SERVER_PUBLIC_PARAMS)
Base64.decode(BuildConfig.ZKGROUP_SERVER_PUBLIC_PARAMS),
Base64.decode(BuildConfig.GENERIC_SERVER_PUBLIC_PARAMS)
)
serviceNetworkAccessMock = mock {

View file

@ -313,12 +313,13 @@ public class SQLiteDatabase implements SupportSQLiteDatabase {
public void endTransaction() {
trace("endTransaction()", wrapped::endTransaction);
traceLockEnd();
Set<Runnable> tasks = getPostSuccessfulTransactionTasks();
for (Runnable r : new HashSet<>(tasks)) {
r.run();
if (!wrapped.inTransaction()) {
Set<Runnable> tasks = getPostSuccessfulTransactionTasks();
for (Runnable r : new HashSet<>(tasks)) {
r.run();
}
tasks.clear();
}
tasks.clear();
}
public void setTransactionSuccessful() {