2929// SOFTWARE.
3030//
3131
32- #if compiler(>=6.0)
32+ #if !canImport(Darwin)
33+
34+ import Synchronization
35+
36+ typealias Mutex = Synchronization . Mutex
37+
38+ #endif
39+
3340/// Invokes the passed in closure with an `IdentifableContinuation` for the current task.
3441///
3542/// The body of the closure executes synchronously on the calling actor. Once it returns the calling task is suspended.
4552/// - handler: Cancellation closure executed when the current Task is cancelled. Handler is always
4653/// called _after_ the body closure is completed.
4754/// - Returns: The value continuation is resumed with.
48- @inlinable
4955public func withIdentifiableContinuation< T> (
5056 isolation: isolated ( any Actor ) ? = #isolation,
5157 function: String = #function,
@@ -54,7 +60,9 @@ public func withIdentifiableContinuation<T>(
5460) async -> T {
5561 let id = IdentifiableContinuation < T , Never > . ID ( )
5662 let state = Mutex ( ( isStarted: false , isCancelled: false ) )
63+ #if compiler(<6.2)
5764 nonisolated ( unsafe) let body = body
65+ #endif
5866 return await withTaskCancellationHandler {
5967 await withCheckedContinuation ( isolation: isolation, function: function) {
6068 let continuation = IdentifiableContinuation ( id: id, continuation: $0)
@@ -93,7 +101,6 @@ public func withIdentifiableContinuation<T>(
93101/// - handler: Cancellation closure executed when the current Task is cancelled. Handler is always
94102/// called _after_ the body closure is completed.
95103/// - Returns: The value continuation is resumed with.
96- @inlinable
97104public func withIdentifiableThrowingContinuation< T> (
98105 isolation: isolated ( any Actor ) ? = #isolation,
99106 function: String = #function,
@@ -102,7 +109,9 @@ public func withIdentifiableThrowingContinuation<T>(
102109) async throws -> T {
103110 let id = IdentifiableContinuation < T , any Error > . ID ( )
104111 let state = Mutex ( ( isStarted: false , isCancelled: false ) )
112+ #if compiler(<6.2)
105113 nonisolated ( unsafe) let body = body
114+ #endif
106115 return try await withTaskCancellationHandler {
107116 try await withCheckedThrowingContinuation ( isolation: isolation, function: function) {
108117 let continuation = IdentifiableContinuation ( id: id, continuation: $0)
@@ -125,113 +134,13 @@ public func withIdentifiableThrowingContinuation<T>(
125134 }
126135 }
127136}
128- #else
129- /// Invokes the passed in closure with an `IdentifableContinuation` for the current task.
130- ///
131- /// The body of the closure executes synchronously on the calling actor. Once it returns the calling task is suspended.
132- /// It is possible to immediately resume the task, or escape the continuation in order to complete it afterwards, which
133- /// will then resume the suspended task.
134- ///
135- /// You must invoke the continuation's `resume` method exactly once.
136- /// - Parameters:
137- /// - isolation: Actor isolation used when executing the body closure.
138- /// - function: A string identifying the declaration that is the notional
139- /// source for the continuation, used to identify the continuation in
140- /// runtime diagnostics related to misuse of this continuation.
141- /// - body: A closure that takes a `IdentifiableContinuation` parameter.
142- /// - handler: Cancellation closure executed when the current Task is cancelled. Handler is always called _after_ the body closure is compeled.
143- /// - Returns: The value continuation is resumed with.
144- @_unsafeInheritExecutor
145- @inlinable
146- public func withIdentifiableContinuation< T> (
147- isolation: isolated some Actor ,
148- function: String = #function,
149- body: ( IdentifiableContinuation < T , Never > ) -> Void ,
150- onCancel handler: @Sendable ( IdentifiableContinuation < T , Never > . ID ) -> Void
151- ) async -> T {
152- let id = IdentifiableContinuation < T , Never > . ID ( )
153- let state = Mutex ( ( isStarted: false , isCancelled: false ) )
154- return await withTaskCancellationHandler {
155- await withCheckedContinuation ( function: function) {
156- let continuation = IdentifiableContinuation ( id: id, continuation: $0)
157- body ( continuation)
158- let sendCancel = state. withLock {
159- $0. isStarted = true
160- return $0. isCancelled
161- }
162- if sendCancel {
163- handler ( id)
164- }
165- _ = isolation
166- }
167- } onCancel: {
168- let sendCancel = state. withLock {
169- $0. isCancelled = true
170- return $0. isStarted
171- }
172- if sendCancel {
173- handler ( id)
174- }
175- }
176- }
177-
178- /// Invokes the passed in closure with an `IdentifableContinuation` for the current task.
179- ///
180- /// The body of the closure executes synchronously on the calling actor. Once it returns the calling task is suspended.
181- /// It is possible to immediately resume the task, or escape the continuation in order to complete it afterwards, which
182- /// will then resume the suspended task.
183- ///
184- /// You must invoke the continuation's `resume` method exactly once.
185- /// - Parameters:
186- /// - isolation: Actor isolation used when executing the body closure.
187- /// - function: A string identifying the declaration that is the notional
188- /// source for the continuation, used to identify the continuation in
189- /// runtime diagnostics related to misuse of this continuation.
190- /// - body: A closure that takes a `IdentifiableContinuation` parameter.
191- /// - handler: Cancellation closure executed when the current Task is cancelled. Handler is always called _after_ the body closure is compeled.
192- /// - Returns: The value continuation is resumed with.
193- @_unsafeInheritExecutor
194- @inlinable
195- public func withIdentifiableThrowingContinuation< T> (
196- isolation: isolated some Actor ,
197- function: String = #function,
198- body: ( IdentifiableContinuation < T , any Error > ) -> Void ,
199- onCancel handler: @Sendable ( IdentifiableContinuation < T , any Error > . ID ) -> Void
200- ) async throws -> T {
201- let id = IdentifiableContinuation < T , any Error > . ID ( )
202- let state = Mutex ( ( isStarted: false , isCancelled: false ) )
203- return try await withTaskCancellationHandler {
204- try await withCheckedThrowingContinuation ( function: function) {
205- let continuation = IdentifiableContinuation ( id: id, continuation: $0)
206- body ( continuation)
207- let sendCancel = state. withLock {
208- $0. isStarted = true
209- return $0. isCancelled
210- }
211- if sendCancel {
212- handler ( id)
213- }
214- _ = isolation
215- }
216- } onCancel: {
217- let sendCancel = state. withLock {
218- $0. isCancelled = true
219- return $0. isStarted
220- }
221- if sendCancel {
222- handler ( id)
223- }
224- }
225- }
226- #endif
227137
228138public struct IdentifiableContinuation < T, E> : Sendable , Identifiable where E: Error {
229139
230140 public let id : ID
231141
232142 public final class ID : Hashable , Sendable {
233143
234- @usableFromInline
235144 init ( ) { }
236145
237146 public func hash( into hasher: inout Hasher ) {
@@ -243,31 +152,20 @@ public struct IdentifiableContinuation<T, E>: Sendable, Identifiable where E: Er
243152 }
244153 }
245154
246- @usableFromInline
247155 init ( id: ID , continuation: CheckedContinuation < T , E > ) {
248156 self . id = id
249157 self . continuation = continuation
250158 }
251159
252160 private let continuation : CheckedContinuation < T , E >
253161
254- #if compiler(>=6.0)
255162 public func resume( returning value: sending T) {
256163 continuation. resume ( returning: value)
257164 }
258165
259166 public func resume( with result: sending Result< T , E > ) {
260167 continuation. resume ( with: result)
261168 }
262- #else
263- public func resume( returning value: T ) {
264- continuation. resume ( returning: value)
265- }
266-
267- public func resume( with result: Result < T , E > ) {
268- continuation. resume ( with: result)
269- }
270- #endif
271169
272170 public func resume( throwing error: E ) {
273171 continuation. resume ( throwing: error)
0 commit comments