Created
June 3, 2022 13:06
-
-
Save NikolaiRuhe/0f41cf5d223f751e35ab9d6a98093e63 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// A type that synchronizes progress of two tasks. | |
/// | |
/// After setup, two tasks should eventually call the `join` function. The | |
/// first task will suspend until the second task arrives and calls `join` as | |
/// well. Both tasks resume normally after that. | |
public final actor TaskRendezvous: Sendable { | |
private var completion: CheckedContinuation<Void, Error>? = nil | |
/// Suspends until a second task calls `join()` on this instance. | |
public func join() async throws { | |
return try await withCheckedThrowingContinuation { newCompletion in | |
if let oldCompletion = completion { | |
self.completion = nil | |
oldCompletion.resume() | |
newCompletion.resume() | |
} else { | |
self.completion = newCompletion | |
} | |
} | |
} | |
/// Lets two tasks synchronize so that both perform the closure at the same | |
/// time. | |
/// | |
/// 1. Waits until a second task joined. | |
/// 2. Performs the passed closure while the other task performs its closure. | |
/// 3. Waits again for the second task to complete its closure. | |
public func meet<T>(_ perform: () async throws -> T) async throws -> T { | |
try await join() | |
let result = try await perform() | |
try await join() | |
return result | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment