@@ -19,7 +19,10 @@ import Swift
19
19
internal func _swiftJobRun( _ job: UnownedJob ,
20
20
_ executor: UnownedSerialExecutor ) -> ( )
21
21
22
- /// A job is a unit of scheduleable work.
22
+ /// A unit of scheduleable work.
23
+ ///
24
+ /// Unless you're implementing a scheduler,
25
+ /// you don't generally interact with jobs directly.
23
26
@available ( SwiftStdlib 5 . 1 , * )
24
27
@frozen
25
28
public struct UnownedJob: Sendable {
@@ -32,6 +35,38 @@ public struct UnownedJob: Sendable {
32
35
}
33
36
}
34
37
38
+ /// A mechanism to interface
39
+ /// between synchronous and asynchronous code,
40
+ /// without correctness checking.
41
+ ///
42
+ /// A *continuation* is an opaque representation of program state.
43
+ /// To create a continuation in asynchronous code,
44
+ /// call the `withUnsafeContinuation(_:)` or
45
+ /// `withUnsafeThrowingContinuation(_:)` function.
46
+ /// To resume the asynchronous task,
47
+ /// call the `resume(returning:)`,
48
+ /// `resume(throwing:)`,
49
+ /// `resume(with:)`,
50
+ /// or `resume()` method.
51
+ ///
52
+ /// - Important: You must call a resume method exactly once
53
+ /// on every execution path throughout the program.
54
+ /// Resuming from a continuation more than once is undefined behavior.
55
+ /// Never resuming leaves the task in a suspended state indefinitely,
56
+ /// and leaks any associated resources.
57
+ ///
58
+ /// `CheckedContinuation` performs runtime checks
59
+ /// for missing or multiple resume operations.
60
+ /// `UnsafeContinuation` avoids enforcing these invariants at runtime
61
+ /// because it aims to be a low-overhead mechanism
62
+ /// for interfacing Swift tasks with
63
+ /// event loops, delegate methods, callbacks,
64
+ /// and other non-`async` scheduling mechanisms.
65
+ /// However, during development, the ability to verify that the
66
+ /// invariants are being upheld in testing is important.
67
+ /// Because both types have the same interface,
68
+ /// you can replace one with the other in most circumstances,
69
+ /// without making other changes.
35
70
@available ( SwiftStdlib 5 . 1 , * )
36
71
@frozen
37
72
public struct UnsafeContinuation < T, E: Error > : Sendable {
@@ -42,18 +77,19 @@ public struct UnsafeContinuation<T, E: Error>: Sendable {
42
77
self . context = context
43
78
}
44
79
45
- /// Resume the task awaiting the continuation by having it return normally
46
- /// from its suspension point .
80
+ /// Resume the task that's awaiting the continuation
81
+ /// by returning the given value .
47
82
///
48
83
/// - Parameter value: The value to return from the continuation.
49
84
///
50
- /// A continuation must be resumed exactly once. If the continuation has
51
- /// already been resumed through this object, then the attempt to resume
52
- /// the continuation again will result in undefined behavior.
85
+ /// A continuation must be resumed exactly once.
86
+ /// If the continuation has already resumed,
87
+ /// then calling this method results in undefined behavior.
53
88
///
54
- /// After `resume` enqueues the task, control is immediately returned to
55
- /// the caller. The task will continue executing when its executor is
56
- /// able to reschedule it.
89
+ /// After calling this method,
90
+ /// control immediately returns to the caller.
91
+ /// The task continues executing
92
+ /// when its executor schedules it.
57
93
@_alwaysEmitIntoClient
58
94
public func resume( returning value: __owned T) where E == Never {
59
95
#if compiler(>=5.5) && $BuiltinContinuation
@@ -63,18 +99,19 @@ public struct UnsafeContinuation<T, E: Error>: Sendable {
63
99
#endif
64
100
}
65
101
66
- /// Resume the task awaiting the continuation by having it return normally
67
- /// from its suspension point .
102
+ /// Resume the task that's awaiting the continuation
103
+ /// by returning the given value .
68
104
///
69
105
/// - Parameter value: The value to return from the continuation.
70
106
///
71
- /// A continuation must be resumed exactly once. If the continuation has
72
- /// already been resumed through this object, then the attempt to resume
73
- /// the continuation again will result in undefined behavior.
107
+ /// A continuation must be resumed exactly once.
108
+ /// If the continuation has already resumed,
109
+ /// then calling this method results in undefined behavior.
74
110
///
75
- /// After `resume` enqueues the task, control is immediately returned to
76
- /// the caller. The task will continue executing when its executor is
77
- /// able to reschedule it.
111
+ /// After calling this method,
112
+ /// control immediately returns to the caller.
113
+ /// The task continues executing
114
+ /// when its executor schedules it.
78
115
@_alwaysEmitIntoClient
79
116
public func resume( returning value: __owned T) {
80
117
#if compiler(>=5.5) && $BuiltinContinuation
@@ -84,18 +121,19 @@ public struct UnsafeContinuation<T, E: Error>: Sendable {
84
121
#endif
85
122
}
86
123
87
- /// Resume the task awaiting the continuation by having it throw an error
88
- /// from its suspension point .
124
+ /// Resume the task that's awaiting the continuation
125
+ /// by throwing the given error .
89
126
///
90
127
/// - Parameter error: The error to throw from the continuation.
91
128
///
92
- /// A continuation must be resumed exactly once. If the continuation has
93
- /// already been resumed through this object, then the attempt to resume
94
- /// the continuation again will result in undefined behavior.
129
+ /// A continuation must be resumed exactly once.
130
+ /// If the continuation has already resumed,
131
+ /// then calling this method results in undefined behavior.
95
132
///
96
- /// After `resume` enqueues the task, control is immediately returned to
97
- /// the caller. The task will continue executing when its executor is
98
- /// able to reschedule it.
133
+ /// After calling this method,
134
+ /// control immediately returns to the caller.
135
+ /// The task continues executing
136
+ /// when its executor schedules it.
99
137
@_alwaysEmitIntoClient
100
138
public func resume( throwing error: __owned E) {
101
139
#if compiler(>=5.5) && $BuiltinContinuation
@@ -108,20 +146,22 @@ public struct UnsafeContinuation<T, E: Error>: Sendable {
108
146
109
147
@available ( SwiftStdlib 5 . 1 , * )
110
148
extension UnsafeContinuation {
111
- /// Resume the task awaiting the continuation by having it either
112
- /// return normally or throw an error based on the state of the given
113
- /// `Result` value.
149
+ /// Resume the task that's awaiting the continuation
150
+ /// by returning or throwing the given result value.
114
151
///
115
- /// - Parameter result: A value to either return or throw from the
116
- /// continuation.
152
+ /// - Parameter result: The result.
153
+ /// If it contains a `.success` value,
154
+ /// the continuation returns that value;
155
+ /// otherwise, it throws the `.error` value.
117
156
///
118
- /// A continuation must be resumed exactly once. If the continuation has
119
- /// already been resumed through this object, then the attempt to resume
120
- /// the continuation again will trap .
157
+ /// A continuation must be resumed exactly once.
158
+ /// If the continuation has already resumed,
159
+ /// then calling this method results in undefined behavior .
121
160
///
122
- /// After `resume` enqueues the task, control is immediately returned to
123
- /// the caller. The task will continue executing when its executor is
124
- /// able to reschedule it.
161
+ /// After calling this method,
162
+ /// control immediately returns to the caller.
163
+ /// The task continues executing
164
+ /// when its executor schedules it.
125
165
@_alwaysEmitIntoClient
126
166
public func resume< Er: Error > ( with result: Result < T , Er > ) where E == Error {
127
167
switch result {
@@ -132,20 +172,22 @@ extension UnsafeContinuation {
132
172
}
133
173
}
134
174
135
- /// Resume the task awaiting the continuation by having it either
136
- /// return normally or throw an error based on the state of the given
137
- /// `Result` value.
175
+ /// Resume the task that's awaiting the continuation
176
+ /// by returning or throwing the given result value.
138
177
///
139
- /// - Parameter result: A value to either return or throw from the
140
- /// continuation.
178
+ /// - Parameter result: The result.
179
+ /// If it contains a `.success` value,
180
+ /// the continuation returns that value;
181
+ /// otherwise, it throws the `.error` value.
141
182
///
142
- /// A continuation must be resumed exactly once. If the continuation has
143
- /// already been resumed through this object, then the attempt to resume
144
- /// the continuation again will trap .
183
+ /// A continuation must be resumed exactly once.
184
+ /// If the continuation has already resumed,
185
+ /// then calling this method results in undefined behavior .
145
186
///
146
- /// After `resume` enqueues the task, control is immediately returned to
147
- /// the caller. The task will continue executing when its executor is
148
- /// able to reschedule it.
187
+ /// After calling this method,
188
+ /// control immediately returns to the caller.
189
+ /// The task continues executing
190
+ /// when its executor schedules it.
149
191
@_alwaysEmitIntoClient
150
192
public func resume( with result: Result < T , E > ) {
151
193
switch result {
@@ -156,16 +198,16 @@ extension UnsafeContinuation {
156
198
}
157
199
}
158
200
159
- /// Resume the task awaiting the continuation by having it return normally
160
- /// from its suspension point.
201
+ /// Resume the task that's awaiting the continuation by returning.
161
202
///
162
- /// A continuation must be resumed exactly once. If the continuation has
163
- /// already been resumed through this object, then the attempt to resume
164
- /// the continuation again will trap .
203
+ /// A continuation must be resumed exactly once.
204
+ /// If the continuation has already resumed,
205
+ /// then calling this method results in undefined behavior .
165
206
///
166
- /// After `resume` enqueues the task, control is immediately returned to
167
- /// the caller. The task will continue executing when its executor is
168
- /// able to reschedule it.
207
+ /// After calling this method,
208
+ /// control immediately returns to the caller.
209
+ /// The task continues executing
210
+ /// when its executor schedules it.
169
211
@_alwaysEmitIntoClient
170
212
public func resume( ) where T == Void {
171
213
self . resume ( returning: ( ) )
@@ -204,9 +246,13 @@ internal func _resumeUnsafeThrowingContinuationWithError<T>(
204
246
205
247
#endif
206
248
207
- /// The operation functions must resume the continuation *exactly once*.
249
+ /// Suspends the current task,
250
+ /// then calls the given closure with an unsafe continuation for the current task.
208
251
///
209
- /// The continuation will not begin executing until the operation function returns.
252
+ /// - Parameter fn: A closure that takes an `UnsafeContinuation` parameter.
253
+ /// You must resume the continuation exactly once.
254
+ ///
255
+ /// - Returns: The value passed to the continuation by the closure.
210
256
@available ( SwiftStdlib 5 . 1 , * )
211
257
@_alwaysEmitIntoClient
212
258
public func withUnsafeContinuation< T> (
@@ -217,9 +263,16 @@ public func withUnsafeContinuation<T>(
217
263
}
218
264
}
219
265
220
- /// The operation functions must resume the continuation *exactly once*.
266
+ /// Suspends the current task,
267
+ /// then calls the given closure with an unsafe throwing continuation for the current task.
268
+ ///
269
+ /// - Parameter fn: A closure that takes an `UnsafeContinuation` parameter.
270
+ /// You must resume the continuation exactly once.
271
+ ///
272
+ /// - Returns: The value passed to the continuation by the closure.
221
273
///
222
- /// The continuation will not begin executing until the operation function returns.
274
+ /// If `resume(throwing:)` is called on the continuation,
275
+ /// this function throws that error.
223
276
@available ( SwiftStdlib 5 . 1 , * )
224
277
@_alwaysEmitIntoClient
225
278
public func withUnsafeThrowingContinuation< T> (
0 commit comments