@@ -52,13 +52,66 @@ public actor CancellationSource {
5252 linkedSources. append ( source)
5353 }
5454
55+ /// Propagate cancellation to linked cancellation sources.
56+ @inlinable
57+ nonisolated func _propagateCancellation( ) async {
58+ await withTaskGroup ( of: Void . self) { group in
59+ let linkedSources = await linkedSources
60+ linkedSources. forEach { group. addTask ( operation: $0. cancel) }
61+ await group. waitForAll ( )
62+ }
63+ }
64+
5565 // MARK: Public
5666
5767 /// Creates a new cancellation source object.
5868 ///
5969 /// - Returns: The newly created cancellation source.
6070 public init ( ) { }
6171
72+ #if swift(>=5.7)
73+ /// Creates a new cancellation source object linking to all the provided cancellation sources.
74+ ///
75+ /// Initiating cancellation in any of the provided cancellation sources
76+ /// will ensure newly created cancellation source receive cancellation event.
77+ ///
78+ /// - Parameter sources: The cancellation sources the newly created object will be linked to.
79+ ///
80+ /// - Returns: The newly created cancellation source.
81+ public nonisolated init ( linkedWith sources: [ CancellationSource ] ) async {
82+ await withTaskGroup ( of: Void . self) { group in
83+ sources. forEach { source in
84+ group. addTask { await source. _addSource ( self ) }
85+ }
86+ await group. waitForAll ( )
87+ }
88+ }
89+
90+ /// Creates a new cancellation source object linking to all the provided cancellation sources.
91+ ///
92+ /// Initiating cancellation in any of the provided cancellation sources
93+ /// will ensure newly created cancellation source receive cancellation event.
94+ ///
95+ /// - Parameter sources: The cancellation sources the newly created object will be linked to.
96+ ///
97+ /// - Returns: The newly created cancellation source.
98+ public init ( linkedWith sources: CancellationSource ... ) async {
99+ await self . init ( linkedWith: sources)
100+ }
101+
102+ /// Creates a new cancellation source object
103+ /// and triggers cancellation event on this object after specified timeout.
104+ ///
105+ /// - Parameter nanoseconds: The delay after which cancellation event triggered.
106+ ///
107+ /// - Returns: The newly created cancellation source.
108+ public init ( cancelAfterNanoseconds nanoseconds: UInt64 ) {
109+ self . init ( )
110+ Task { [ weak self] in
111+ try await self ? . cancel ( afterNanoseconds: nanoseconds)
112+ }
113+ }
114+ #else
62115 /// Creates a new cancellation source object linking to all the provided cancellation sources.
63116 ///
64117 /// Initiating cancellation in any of the provided cancellation sources
@@ -100,6 +153,7 @@ public actor CancellationSource {
100153 try await self ? . cancel ( afterNanoseconds: nanoseconds)
101154 }
102155 }
156+ #endif
103157
104158 /// Register task for cooperative cancellation when cancellation event received on cancellation source.
105159 ///
@@ -120,10 +174,7 @@ public actor CancellationSource {
120174 public func cancel( ) async {
121175 registeredTasks. forEach { $1 ( ) }
122176 registeredTasks = [ : ]
123- await withTaskGroup ( of: Void . self) { group in
124- linkedSources. forEach { group. addTask ( operation: $0. cancel) }
125- await group. waitForAll ( )
126- }
177+ await _propagateCancellation ( )
127178 }
128179
129180 /// Trigger cancellation event after provided delay,
@@ -143,16 +194,17 @@ public extension Task {
143194 /// Runs the given non-throwing operation asynchronously as part of a new task on behalf of the current actor,
144195 /// with the provided cancellation source controlling cooperative cancellation.
145196 ///
146- /// A child task with the provided operation is created, cancellation of which is controlled by provided cancellation source.
147- /// In the event of cancellation child task is cancelled, while returning the value in the returned task.
148- /// In case you want to register and track the top-level task for cancellation use the async initializer instead.
197+ /// A top-level task with the provided operation is created, cancellation of which is controlled by provided cancellation source.
198+ /// In the event of cancellation top-level task is cancelled, while returning the value in the returned task.
149199 ///
150200 /// - Parameters:
151201 /// - priority: The priority of the task. Pass `nil` to use the priority from `Task.currentPriority`.
152202 /// - cancellationSource: The cancellation source on which new task will be registered for cancellation.
153203 /// - operation: The operation to perform.
154204 ///
155205 /// - Returns: The newly created task.
206+ /// - Note: In case you want to register and track the top-level task
207+ /// for cancellation use the async initializer instead.
156208 @discardableResult
157209 init (
158210 priority: TaskPriority ? = nil ,
@@ -169,16 +221,17 @@ public extension Task {
169221 /// Runs the given throwing operation asynchronously as part of a new task on behalf of the current actor,
170222 /// with the provided cancellation source controlling cooperative cancellation.
171223 ///
172- /// A child task with the provided operation is created, cancellation of which is controlled by provided cancellation source.
173- /// In the event of cancellation child task is cancelled, while propagating error in the returned task.
174- /// In case you want to register and track the top-level task for cancellation use the async initializer instead.
224+ /// A top-level task with the provided operation is created, cancellation of which is controlled by provided cancellation source.
225+ /// In the event of cancellation top-level task is cancelled, while propagating error in the returned task.
175226 ///
176227 /// - Parameters:
177228 /// - priority: The priority of the task. Pass `nil` to use the priority from `Task.currentPriority`.
178229 /// - cancellationSource: The cancellation source on which new task will be registered for cancellation.
179230 /// - operation: The operation to perform.
180231 ///
181232 /// - Returns: The newly created task.
233+ /// - Note: In case you want to register and track the top-level task
234+ /// for cancellation use the async initializer instead.
182235 @discardableResult
183236 init (
184237 priority: TaskPriority ? = nil ,
@@ -195,16 +248,17 @@ public extension Task {
195248 /// Runs the given non-throwing operation asynchronously as part of a new task,
196249 /// with the provided cancellation source controlling cooperative cancellation.
197250 ///
198- /// A child task with the provided operation is created, cancellation of which is controlled by provided cancellation source.
199- /// In the event of cancellation child task is cancelled, while returning the value in the returned task.
200- /// In case you want to register and track the top-level task for cancellation use the async initializer instead.
251+ /// A top-level task with the provided operation is created, cancellation of which is controlled by provided cancellation source.
252+ /// In the event of cancellation top-level task is cancelled, while returning the value in the returned task.
201253 ///
202254 /// - Parameters:
203- /// - priority: The priority of the task. Pass `nil` to use the priority from `Task.currentPriority`.
255+ /// - priority: The priority of the task.
204256 /// - cancellationSource: The cancellation source on which new task will be registered for cancellation.
205257 /// - operation: The operation to perform.
206258 ///
207259 /// - Returns: The newly created task.
260+ /// - Note: In case you want to register and track the top-level task
261+ /// for cancellation use the async initializer instead.
208262 @discardableResult
209263 static func detached(
210264 priority: TaskPriority ? = nil ,
@@ -221,16 +275,17 @@ public extension Task {
221275 /// Runs the given throwing operation asynchronously as part of a new task,
222276 /// with the provided cancellation source controlling cooperative cancellation.
223277 ///
224- /// A child task with the provided operation is created, cancellation of which is controlled by provided cancellation source.
225- /// In the event of cancellation child task is cancelled, while returning the value in the returned task.
226- /// In case you want to register and track the top-level task for cancellation use the async initializer instead.
278+ /// A top-level task with the provided operation is created, cancellation of which is controlled by provided cancellation source.
279+ /// In the event of cancellation top-level task is cancelled, while returning the value in the returned task.
227280 ///
228281 /// - Parameters:
229- /// - priority: The priority of the task. Pass `nil` to use the priority from `Task.currentPriority`.
282+ /// - priority: The priority of the task.
230283 /// - cancellationSource: The cancellation source on which new task will be registered for cancellation.
231284 /// - operation: The operation to perform.
232285 ///
233286 /// - Returns: The newly created task.
287+ /// - Note: In case you want to register and track the top-level task
288+ /// for cancellation use the async initializer instead.
234289 @discardableResult
235290 static func detached(
236291 priority: TaskPriority ? = nil ,
@@ -292,7 +347,7 @@ public extension Task {
292347 /// The created task will be cancelled when cancellation event triggered on the provided cancellation source.
293348 ///
294349 /// - Parameters:
295- /// - priority: The priority of the task. Pass `nil` to use the priority from `Task.currentPriority`.
350+ /// - priority: The priority of the task.
296351 /// - cancellationSource: The cancellation source on which new task will be registered for cancellation.
297352 /// - operation: The operation to perform.
298353 ///
@@ -314,7 +369,7 @@ public extension Task {
314369 /// The created task will be cancelled when cancellation event triggered on the provided cancellation source.
315370 ///
316371 /// - Parameters:
317- /// - priority: The priority of the task. Pass `nil` to use the priority from `Task.currentPriority`.
372+ /// - priority: The priority of the task.
318373 /// - cancellationSource: The cancellation source on which new task will be registered for cancellation.
319374 /// - operation: The operation to perform.
320375 ///
0 commit comments