Skip to content

Commit a703da9

Browse files
committed
Async version of Pool.barrier { ... }
1 parent 684266b commit a703da9

File tree

1 file changed

+11
-0
lines changed

1 file changed

+11
-0
lines changed

GRDB/Utils/Pool.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ final class Pool<T: Sendable>: Sendable {
6363
private let itemsSemaphore: DispatchSemaphore // limits the number of elements
6464
private let itemsGroup: DispatchGroup // knows when no element is used
6565
private let barrierQueue: DispatchQueue
66+
private let barrierActor: DispatchQueueActor
6667
private let semaphoreWaitingQueue: DispatchQueue // Inspired by https://khanlou.com/2016/04/the-GCD-handbook/
6768
private let semaphoreWaitingActor: DispatchQueueActor
6869

@@ -84,6 +85,7 @@ final class Pool<T: Sendable>: Sendable {
8485
self.itemsSemaphore = DispatchSemaphore(value: maximumCount)
8586
self.itemsGroup = DispatchGroup()
8687
self.barrierQueue = DispatchQueue(label: "GRDB.Pool.barrier", qos: qos, attributes: [.concurrent])
88+
self.barrierActor = DispatchQueueActor(queue: barrierQueue, flags: [.barrier])
8789
self.semaphoreWaitingQueue = DispatchQueue(label: "GRDB.Pool.wait", qos: qos)
8890
self.semaphoreWaitingActor = DispatchQueueActor(queue: semaphoreWaitingQueue)
8991
}
@@ -203,6 +205,15 @@ final class Pool<T: Sendable>: Sendable {
203205
}
204206
}
205207

208+
func barrier<R: Sendable>(
209+
execute barrier: sending () throws -> sending R
210+
) async rethrows -> sending R {
211+
try await barrierActor.execute {
212+
itemsGroup.wait()
213+
return try barrier()
214+
}
215+
}
216+
206217
/// Asynchronously runs the `barrier` function when no element is used, and
207218
/// before any other element is dequeued.
208219
func asyncBarrier(execute barrier: @escaping @Sendable () -> Void) {

0 commit comments

Comments
 (0)