29
29
// SOFTWARE.
30
30
//
31
31
32
- #if compiler(>=6.0)
32
+ #if !canImport(Darwin)
33
+
34
+ import Synchronization
35
+
36
+ typealias Mutex = Synchronization . Mutex
37
+
38
+ #endif
39
+
33
40
/// Invokes the passed in closure with an `IdentifableContinuation` for the current task.
34
41
///
35
42
/// The body of the closure executes synchronously on the calling actor. Once it returns the calling task is suspended.
45
52
/// - handler: Cancellation closure executed when the current Task is cancelled. Handler is always
46
53
/// called _after_ the body closure is completed.
47
54
/// - Returns: The value continuation is resumed with.
48
- @inlinable
49
55
public func withIdentifiableContinuation< T> (
50
56
isolation: isolated ( any Actor ) ? = #isolation,
51
57
function: String = #function,
@@ -54,7 +60,9 @@ public func withIdentifiableContinuation<T>(
54
60
) async -> T {
55
61
let id = IdentifiableContinuation < T , Never > . ID ( )
56
62
let state = Mutex ( ( isStarted: false , isCancelled: false ) )
63
+ #if compiler(<6.2)
57
64
nonisolated ( unsafe) let body = body
65
+ #endif
58
66
return await withTaskCancellationHandler {
59
67
await withCheckedContinuation ( isolation: isolation, function: function) {
60
68
let continuation = IdentifiableContinuation ( id: id, continuation: $0)
@@ -93,7 +101,6 @@ public func withIdentifiableContinuation<T>(
93
101
/// - handler: Cancellation closure executed when the current Task is cancelled. Handler is always
94
102
/// called _after_ the body closure is completed.
95
103
/// - Returns: The value continuation is resumed with.
96
- @inlinable
97
104
public func withIdentifiableThrowingContinuation< T> (
98
105
isolation: isolated ( any Actor ) ? = #isolation,
99
106
function: String = #function,
@@ -102,7 +109,9 @@ public func withIdentifiableThrowingContinuation<T>(
102
109
) async throws -> T {
103
110
let id = IdentifiableContinuation < T , any Error > . ID ( )
104
111
let state = Mutex ( ( isStarted: false , isCancelled: false ) )
112
+ #if compiler(<6.2)
105
113
nonisolated ( unsafe) let body = body
114
+ #endif
106
115
return try await withTaskCancellationHandler {
107
116
try await withCheckedThrowingContinuation ( isolation: isolation, function: function) {
108
117
let continuation = IdentifiableContinuation ( id: id, continuation: $0)
@@ -125,113 +134,13 @@ public func withIdentifiableThrowingContinuation<T>(
125
134
}
126
135
}
127
136
}
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
227
137
228
138
public struct IdentifiableContinuation < T, E> : Sendable , Identifiable where E: Error {
229
139
230
140
public let id : ID
231
141
232
142
public final class ID : Hashable , Sendable {
233
143
234
- @usableFromInline
235
144
init ( ) { }
236
145
237
146
public func hash( into hasher: inout Hasher ) {
@@ -243,31 +152,20 @@ public struct IdentifiableContinuation<T, E>: Sendable, Identifiable where E: Er
243
152
}
244
153
}
245
154
246
- @usableFromInline
247
155
init ( id: ID , continuation: CheckedContinuation < T , E > ) {
248
156
self . id = id
249
157
self . continuation = continuation
250
158
}
251
159
252
160
private let continuation : CheckedContinuation < T , E >
253
161
254
- #if compiler(>=6.0)
255
162
public func resume( returning value: sending T) {
256
163
continuation. resume ( returning: value)
257
164
}
258
165
259
166
public func resume( with result: sending Result< T , E > ) {
260
167
continuation. resume ( with: result)
261
168
}
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
271
169
272
170
public func resume( throwing error: E ) {
273
171
continuation. resume ( throwing: error)
0 commit comments