Skip to content

Commit 6069e6d

Browse files
committed
DatabasePool.barrierWriteWithoutTransaction can access task locals
1 parent a703da9 commit 6069e6d

File tree

1 file changed

+23
-11
lines changed

1 file changed

+23
-11
lines changed

GRDB/Core/DatabasePool.swift

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -789,20 +789,32 @@ extension DatabasePool: DatabaseWriter {
789789
public func barrierWriteWithoutTransaction<T: Sendable>(
790790
_ updates: @escaping @Sendable (Database) throws -> T
791791
) async throws -> T {
792-
let dbAccess = CancellableDatabaseAccess()
793-
return try await dbAccess.withCancellableContinuation { continuation in
794-
asyncBarrierWriteWithoutTransaction { dbResult in
795-
do {
796-
try dbAccess.checkCancellation()
797-
let db = try dbResult.get()
798-
let result = try dbAccess.inDatabase(db) {
799-
try updates(db)
792+
guard let readerPool else {
793+
throw DatabaseError.connectionIsClosed()
794+
}
795+
796+
// Pool.barrier does not support async calls (yet?).
797+
// So we perform cancellation checks just as in
798+
// the async version of SerializedDatabase.execute().
799+
let cancelMutex = Mutex<(@Sendable () -> Void)?>(nil)
800+
return try await withTaskCancellationHandler {
801+
try Task.checkCancellation()
802+
return try await readerPool.barrier {
803+
try Task.checkCancellation()
804+
let value = try writer.sync { db in
805+
defer {
806+
db.uncancel()
800807
}
801-
continuation.resume(returning: result)
802-
} catch {
803-
continuation.resume(throwing: error)
808+
cancelMutex.store(db.cancel)
809+
try Task.checkCancellation()
810+
return try updates(db)
804811
}
812+
#warning("TODO: remove this check, and fix tests accordingly. The database access has succeeded, it's useless to lose its result.")
813+
try Task.checkCancellation()
814+
return value
805815
}
816+
} onCancel: {
817+
cancelMutex.withLock { $0?() }
806818
}
807819
}
808820

0 commit comments

Comments
 (0)