Skip to content

Commit 57ad1f1

Browse files
authored
Merge pull request #40115 from amartini51/concurrency_docs_to_main
Cherry-pick concurrency docs
2 parents 190f69a + dee26fb commit 57ad1f1

13 files changed

+1422
-774
lines changed

stdlib/public/Concurrency/AsyncIteratorProtocol.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
import Swift
1414

15-
/// A type that that asychronously supplies the values of a sequence one at a
15+
/// A type that asynchronously supplies the values of a sequence one at a
1616
/// time.
1717
///
1818
/// The `AsyncIteratorProtocol` defines the type returned by the

stdlib/public/Concurrency/AsyncSequence.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,8 @@ extension AsyncSequence {
236236
/// The predicate executes each time the asynchronous sequence produces an
237237
/// element, until either the predicate returns `false` or the sequence ends.
238238
///
239+
/// If the asynchronous sequence is empty, this method returns `true`.
240+
///
239241
/// - Parameter predicate: A closure that takes an element of the asynchronous
240242
/// sequence as its argument and returns a Boolean value that indicates
241243
/// whether the passed element satisfies a condition.

stdlib/public/Concurrency/AsyncStream.swift

Lines changed: 250 additions & 91 deletions
Large diffs are not rendered by default.

stdlib/public/Concurrency/AsyncThrowingPrefixWhileSequence.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ extension AsyncSequence {
4343
/// }
4444
/// // Prints: 1 2 3 4 Error: MyError()
4545
///
46-
/// - Parameter isIncluded: A error-throwing closure that takes an element of
46+
/// - Parameter predicate: A error-throwing closure that takes an element of
4747
/// the asynchronous sequence as its argument and returns a Boolean value
4848
/// that indicates whether to include the element in the modified sequence.
4949
/// - Returns: An asynchronous sequence that contains, in order, the elements

stdlib/public/Concurrency/AsyncThrowingStream.swift

Lines changed: 306 additions & 62 deletions
Large diffs are not rendered by default.

stdlib/public/Concurrency/CheckedContinuation.swift

Lines changed: 78 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -83,49 +83,60 @@ internal final class CheckedContinuationCanary: @unchecked Sendable {
8383
}
8484
}
8585

86-
/// A wrapper class for `UnsafeContinuation` that logs misuses of the
87-
/// continuation, logging a message if the continuation is resumed
88-
/// multiple times, or if an object is destroyed without its continuation
89-
/// ever being resumed.
86+
/// A mechanism to interface
87+
/// between synchronous and asynchronous code,
88+
/// logging correctness violations.
9089
///
91-
/// Raw `UnsafeContinuation`, like other unsafe constructs, requires the
92-
/// user to apply it correctly in order to maintain invariants. The key
93-
/// invariant is that the continuation must be resumed exactly once,
94-
/// and bad things happen if this invariant is not upheld--if a continuation
95-
/// is abandoned without resuming the task, then the task will be stuck in
96-
/// the suspended state forever, and conversely, if the same continuation is
97-
/// resumed multiple times, it will put the task in an undefined state.
90+
/// A *continuation* is an opaque representation of program state.
91+
/// To create a continuation in asynchronous code,
92+
/// call the `withUnsafeContinuation(function:_:)` or
93+
/// `withUnsafeThrowingContinuation(function:_:)` function.
94+
/// To resume the asynchronous task,
95+
/// call the `resume(returning:)`,
96+
/// `resume(throwing:)`,
97+
/// `resume(with:)`,
98+
/// or `resume()` method.
9899
///
99-
/// `UnsafeContinuation` avoids enforcing these invariants at runtime because
100-
/// it aims to be a low-overhead mechanism for interfacing Swift tasks with
101-
/// event loops, delegate methods, callbacks, and other non-`async` scheduling
102-
/// mechanisms. However, during development, being able to verify that the
103-
/// invariants are being upheld in testing is important.
100+
/// - Important: You must call a resume method exactly once
101+
/// on every execution path throughout the program.
102+
///
103+
/// Resuming from a continuation more than once is undefined behavior.
104+
/// Never resuming leaves the task in a suspended state indefinitely,
105+
/// and leaks any associated resources.
106+
/// `CheckedContinuation` logs a message
107+
/// if either of these invariants is violated.
104108
///
105-
/// `CheckedContinuation` is designed to be a drop-in API replacement for
106-
/// `UnsafeContinuation` that can be used for testing purposes, at the cost of
107-
/// an extra allocation and indirection for the wrapper object. Changing a call
108-
/// of `withUnsafeContinuation` or `withUnsafeThrowingContinuation` into a call
109-
/// of `withCheckedContinuation` or `withCheckedThrowingContinuation` should be
110-
/// enough to obtain the extra checking without further source modification in
111-
/// most circumstances.
109+
/// `CheckedContinuation` performs runtime checks
110+
/// for missing or multiple resume operations.
111+
/// `UnsafeContinuation` avoids enforcing these invariants at runtime
112+
/// because it aims to be a low-overhead mechanism
113+
/// for interfacing Swift tasks with
114+
/// event loops, delegate methods, callbacks,
115+
/// and other non-`async` scheduling mechanisms.
116+
/// However, during development, the ability to verify that the
117+
/// invariants are being upheld in testing is important.
118+
/// Because both types have the same interface,
119+
/// you can replace one with the other in most circumstances,
120+
/// without making other changes.
112121
@available(SwiftStdlib 5.1, *)
113122
public struct CheckedContinuation<T, E: Error> {
114123
private let canary: CheckedContinuationCanary
115124

116-
/// Initialize a `CheckedContinuation` wrapper around an
117-
/// `UnsafeContinuation`.
125+
/// Creates a checked continuation from an unsafe continuation.
118126
///
119-
/// In most cases, you should use `withCheckedContinuation` or
120-
/// `withCheckedThrowingContinuation` instead. You only need to initialize
127+
/// Instead of calling this initializer,
128+
/// most code calls the `withCheckedContinuation(function:_:)` or
129+
/// `withCheckedThrowingContinuation(function:_:)` function instead.
130+
/// You only need to initialize
121131
/// your own `CheckedContinuation<T, E>` if you already have an
122132
/// `UnsafeContinuation` you want to impose checking on.
123133
///
124134
/// - Parameters:
125-
/// - continuation: a fresh `UnsafeContinuation` that has not yet
126-
/// been resumed. The `UnsafeContinuation` must not be used outside of
127-
/// this object once it's been given to the new object.
128-
/// - function: a string identifying the declaration that is the notional
135+
/// - continuation: An instance of `UnsafeContinuation`
136+
/// that hasn't yet been resumed.
137+
/// After passing the unsafe continuation to this initializer,
138+
/// don't use it outside of this object.
139+
/// - function: A string identifying the declaration that is the notional
129140
/// source for the continuation, used to identify the continuation in
130141
/// runtime diagnostics related to misuse of this continuation.
131142
public init(continuation: UnsafeContinuation<T, E>, function: String = #function) {
@@ -141,10 +152,10 @@ public struct CheckedContinuation<T, E: Error> {
141152
///
142153
/// A continuation must be resumed exactly once. If the continuation has
143154
/// already been resumed through this object, then the attempt to resume
144-
/// the continuation again will trap.
155+
/// the continuation will trap.
145156
///
146-
/// After `resume` enqueues the task, control is immediately returned to
147-
/// the caller. The task will continue executing when its executor is
157+
/// After `resume` enqueues the task, control immediately returns to
158+
/// the caller. The task continues executing when its executor is
148159
/// able to reschedule it.
149160
public func resume(returning value: __owned T) {
150161
if let c: UnsafeContinuation<T, E> = canary.takeContinuation() {
@@ -161,10 +172,10 @@ public struct CheckedContinuation<T, E: Error> {
161172
///
162173
/// A continuation must be resumed exactly once. If the continuation has
163174
/// already been resumed through this object, then the attempt to resume
164-
/// the continuation again will trap.
175+
/// the continuation will trap.
165176
///
166-
/// After `resume` enqueues the task, control is immediately returned to
167-
/// the caller. The task will continue executing when its executor is
177+
/// After `resume` enqueues the task, control immediately returns to
178+
/// the caller. The task continues executing when its executor is
168179
/// able to reschedule it.
169180
public func resume(throwing error: __owned E) {
170181
if let c: UnsafeContinuation<T, E> = canary.takeContinuation() {
@@ -189,10 +200,10 @@ extension CheckedContinuation {
189200
///
190201
/// A continuation must be resumed exactly once. If the continuation has
191202
/// already been resumed through this object, then the attempt to resume
192-
/// the continuation again will trap.
203+
/// the continuation will trap.
193204
///
194-
/// After `resume` enqueues the task, control is immediately returned to
195-
/// the caller. The task will continue executing when its executor is
205+
/// After `resume` enqueues the task, control immediately returns to
206+
/// the caller. The task continues executing when its executor is
196207
/// able to reschedule it.
197208
@_alwaysEmitIntoClient
198209
public func resume<Er: Error>(with result: Result<T, Er>) where E == Error {
@@ -213,10 +224,10 @@ extension CheckedContinuation {
213224
///
214225
/// A continuation must be resumed exactly once. If the continuation has
215226
/// already been resumed through this object, then the attempt to resume
216-
/// the continuation again will trap.
227+
/// the continuation will trap.
217228
///
218-
/// After `resume` enqueues the task, control is immediately returned to
219-
/// the caller. The task will continue executing when its executor is
229+
/// After `resume` enqueues the task, control immediately returns to
230+
/// the caller. The task continues executing when its executor is
220231
/// able to reschedule it.
221232
@_alwaysEmitIntoClient
222233
public func resume(with result: Result<T, E>) {
@@ -233,17 +244,26 @@ extension CheckedContinuation {
233244
///
234245
/// A continuation must be resumed exactly once. If the continuation has
235246
/// already been resumed through this object, then the attempt to resume
236-
/// the continuation again will trap.
247+
/// the continuation will trap.
237248
///
238-
/// After `resume` enqueues the task, control is immediately returned to
239-
/// the caller. The task will continue executing when its executor is
249+
/// After `resume` enqueues the task, control immediately returns to
250+
/// the caller. The task continues executing when its executor is
240251
/// able to reschedule it.
241252
@_alwaysEmitIntoClient
242253
public func resume() where T == Void {
243254
self.resume(returning: ())
244255
}
245256
}
246257

258+
/// Suspends the current task,
259+
/// then calls the given closure with a checked continuation for the current task.
260+
///
261+
/// - Parameters:
262+
/// - function: A string identifying the declaration that is the notional
263+
/// source for the continuation, used to identify the continuation in
264+
/// runtime diagnostics related to misuse of this continuation.
265+
/// - body: A closure that takes a `CheckedContinuation` parameter.
266+
/// You must resume the continuation exactly once.
247267
@available(SwiftStdlib 5.1, *)
248268
public func withCheckedContinuation<T>(
249269
function: String = #function,
@@ -254,6 +274,18 @@ public func withCheckedContinuation<T>(
254274
}
255275
}
256276

277+
/// Suspends the current task,
278+
/// then calls the given closure with a checked throwing continuation for the current task.
279+
///
280+
/// - Parameters:
281+
/// - function: A string identifying the declaration that is the notional
282+
/// source for the continuation, used to identify the continuation in
283+
/// runtime diagnostics related to misuse of this continuation.
284+
/// - body: A closure that takes an `UnsafeContinuation` parameter.
285+
/// You must resume the continuation exactly once.
286+
///
287+
/// If `resume(throwing:)` is called on the continuation,
288+
/// this function throws that error.
257289
@available(SwiftStdlib 5.1, *)
258290
public func withCheckedThrowingContinuation<T>(
259291
function: String = #function,

stdlib/public/Concurrency/Executor.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,13 @@
1212

1313
import Swift
1414

15-
/// A service which can execute jobs.
15+
/// A service that can execute jobs.
1616
@available(SwiftStdlib 5.1, *)
1717
public protocol Executor: AnyObject, Sendable {
1818
func enqueue(_ job: UnownedJob)
1919
}
2020

21-
/// A service which can execute jobs.
21+
/// A service that executes jobs.
2222
@available(SwiftStdlib 5.1, *)
2323
public protocol SerialExecutor: Executor {
2424
// This requirement is repeated here as a non-override so that we

stdlib/public/Concurrency/GlobalActor.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,12 @@ import Swift
1515
/// A type that represents a globally-unique actor that can be used to isolate
1616
/// various declarations anywhere in the program.
1717
///
18-
/// A type that conforms to the `GlobalActor` protocol and is marked with the
18+
/// A type that conforms to the `GlobalActor` protocol and is marked with
1919
/// the `@globalActor` attribute can be used as a custom attribute. Such types
2020
/// are called global actor types, and can be applied to any declaration to
2121
/// specify that such types are isolated to that global actor type. When using
2222
/// such a declaration from another actor (or from nonisolated code),
23-
/// synchronization is performed through the \c shared actor instance to ensure
23+
/// synchronization is performed through the shared actor instance to ensure
2424
/// mutually-exclusive access to the declaration.
2525
@available(SwiftStdlib 5.1, *)
2626
public protocol GlobalActor {

0 commit comments

Comments
 (0)