@@ -22,27 +22,51 @@ import Swift
22
22
/// and reacting to it in that the cancellation handler is _always_ and
23
23
/// _immediately_ invoked when the task is canceled. For example, even if the
24
24
/// operation is running code that never checks for cancellation, a cancellation
25
- /// handler still runs and provides a chance to run some cleanup code.
25
+ /// handler still runs and provides a chance to run some cleanup code:
26
+ ///
27
+ /// ```
28
+ /// await withTaskCancellationHandler {
29
+ /// var sum = 0
30
+ /// while condition {
31
+ /// sum += 1
32
+ /// }
33
+ /// return sum
34
+ /// } onCancel: {
35
+ /// // This onCancel closure might execute concurrently with the operation.
36
+ /// condition.cancel()
37
+ /// }
38
+ /// ```
39
+ ///
40
+ /// ### Execution order and semantics
41
+ /// The `operation` closure is always invoked, even when the
42
+ /// `withTaskCancellationHandler(operation:onCancel:)` method is called from a task
43
+ /// that was already cancelled.
44
+ ///
45
+ /// When `withTaskCancellationHandler(operation:onCancel:)` is used in a task that has already been
46
+ /// cancelled, the cancellation handler will be executed
47
+ /// immediately before the `operation` closure gets to execute.
48
+ ///
49
+ /// This allows the cancellation handler to set some external "cancelled" flag
50
+ /// that the operation may be *atomically* checking for in order to avoid
51
+ /// performing any actual work once the operation gets to run.
52
+ ///
53
+ /// The `operation` closure executes on the calling execution context, and doesn't
54
+ /// suspend or change execution context unless code contained within the closure
55
+ /// does so. In other words, the potential suspension point of the
56
+ /// `withTaskCancellationHandler(operation:onCancel:)` never suspends by itself before
57
+ /// executing the operation.
58
+ ///
59
+ /// If cancellation occurs while the operation is running, the cancellation
60
+ /// handler executes *concurrently* with the operation.
61
+ ///
62
+ /// ### Cancellation handlers and locks
26
63
///
27
64
/// Cancellation handlers which acquire locks must take care to avoid deadlock.
28
65
/// The cancellation handler may be invoked while holding internal locks
29
66
/// associated with the task or other tasks. Other operations on the task, such
30
67
/// as resuming a continuation, may acquire these same internal locks.
31
68
/// Therefore, if a cancellation handler must acquire a lock, other code should
32
69
/// not cancel tasks or resume continuations while holding that lock.
33
- ///
34
- /// Doesn't check for cancellation, and always executes the passed `operation`.
35
- ///
36
- /// The `operation` executes on the calling execution context and does not suspend by itself,
37
- /// unless the code contained within the closure does. If cancellation occurs while the
38
- /// operation is running, the cancellation `handler` will execute *concurrently* with the `operation`.
39
- ///
40
- /// ### Already cancelled tasks
41
- /// When `withTaskCancellationHandler` is used in a `Task` that has already been cancelled,
42
- /// the `onCancel` cancellation ``handler`` will be executed immediately before operation gets
43
- /// to execute. This allows the cancellation handler to set some external "cancelled" flag that the
44
- /// operation may be *atomically* checking for in order to avoid performing any actual work once
45
- /// the operation gets to run.
46
70
@_unsafeInheritExecutor // the operation runs on the same executor as we start out with
47
71
@available ( SwiftStdlib 5 . 1 , * )
48
72
@backDeployed ( before: SwiftStdlib 5.8 )
0 commit comments