@@ -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