@@ -80,6 +80,7 @@ public func withTaskGroup<ChildTaskResult, GroupResult>(
80
80
// Run the withTaskGroup body.
81
81
let result = await body ( & group)
82
82
83
+ // TODO(concurrency): should get isolation from param from withThrowingTaskGroup
83
84
await group. awaitAllRemainingTasks ( )
84
85
85
86
Builtin . destroyTaskGroup ( _group)
@@ -183,13 +184,15 @@ public func withThrowingTaskGroup<ChildTaskResult, GroupResult>(
183
184
// Run the withTaskGroup body.
184
185
let result = try await body ( & group)
185
186
187
+ // TODO(concurrency): should get isolation from param from withThrowingTaskGroup
186
188
await group. awaitAllRemainingTasks ( )
187
189
Builtin . destroyTaskGroup ( _group)
188
190
189
191
return result
190
192
} catch {
191
193
group. cancelAll ( )
192
194
195
+ // TODO(concurrency): should get isolation from param from withThrowingTaskGroup
193
196
await group. awaitAllRemainingTasks ( )
194
197
Builtin . destroyTaskGroup ( _group)
195
198
@@ -563,22 +566,35 @@ public struct TaskGroup<ChildTaskResult: Sendable> {
563
566
/// that method can't be called from a concurrent execution context like a child task.
564
567
///
565
568
/// - Returns: The value returned by the next child task that completes.
566
- public mutating func next( ) async -> ChildTaskResult ? {
569
+ public mutating func next( isolation: isolated ( any Actor ) ? = #isolation) async -> ChildTaskResult ? {
570
+ // try!-safe because this function only exists for Failure == Never,
571
+ // and as such, it is impossible to spawn a throwing child task.
572
+ return try ! await _taskGroupWaitNext ( group: _group) // !-safe cannot throw, we're a non-throwing TaskGroup
573
+ }
574
+
575
+ @usableFromInline
576
+ @_silgen_name ( " $sScG4nextxSgyYaF " )
577
+ internal mutating func __abi_next( ) async -> ChildTaskResult ? {
567
578
// try!-safe because this function only exists for Failure == Never,
568
579
// and as such, it is impossible to spawn a throwing child task.
569
580
return try ! await _taskGroupWaitNext ( group: _group) // !-safe cannot throw, we're a non-throwing TaskGroup
570
581
}
571
582
572
583
/// Await all of the pending tasks added this group.
573
584
@usableFromInline
574
- internal mutating func awaitAllRemainingTasks( ) async {
575
- while let _ = await next ( ) { }
585
+ internal mutating func awaitAllRemainingTasks( isolation: isolated ( any Actor ) ? = #isolation) async {
586
+ while let _ = await next ( isolation: isolation) { }
587
+ }
588
+ @usableFromInline
589
+ @_silgen_name ( " $sScG22awaitAllRemainingTasksyyYaF " )
590
+ internal mutating func __abi_awaitAllRemainingTasks( ) async {
591
+ while let _ = await next ( isolation: nil ) { }
576
592
}
577
593
578
594
/// Wait for all of the group's remaining tasks to complete.
579
595
@_alwaysEmitIntoClient
580
- public mutating func waitForAll( ) async {
581
- await awaitAllRemainingTasks ( )
596
+ public mutating func waitForAll( isolation : isolated ( any Actor ) ? = #isolation ) async {
597
+ await awaitAllRemainingTasks ( isolation : isolation )
582
598
}
583
599
584
600
/// A Boolean value that indicates whether the group has any remaining tasks.
@@ -703,15 +719,19 @@ public struct ThrowingTaskGroup<ChildTaskResult: Sendable, Failure: Error> {
703
719
704
720
/// Await all the remaining tasks on this group.
705
721
@usableFromInline
706
- internal mutating func awaitAllRemainingTasks( ) async {
722
+ internal mutating func awaitAllRemainingTasks( isolation : isolated ( any Actor ) ? = #isolation ) async {
707
723
while true {
708
724
do {
709
- guard let _ = try await next ( ) else {
725
+ guard let _ = try await next ( isolation : isolation ) else {
710
726
return
711
727
}
712
728
} catch { }
713
729
}
714
730
}
731
+ @usableFromInline
732
+ internal mutating func awaitAllRemainingTasks( ) async {
733
+ await awaitAllRemainingTasks ( isolation: nil )
734
+ }
715
735
716
736
@usableFromInline
717
737
internal mutating func _waitForAll( ) async throws {
@@ -750,7 +770,7 @@ public struct ThrowingTaskGroup<ChildTaskResult: Sendable, Failure: Error> {
750
770
/// - Throws: The *first* error that was thrown by a child task during draining all the tasks.
751
771
/// This first error is stored until all other tasks have completed, and is re-thrown afterwards.
752
772
@_alwaysEmitIntoClient
753
- public mutating func waitForAll( ) async throws {
773
+ public mutating func waitForAll( isolation : isolated ( any Actor ) ? = #isolation ) async throws {
754
774
var firstError : Error ? = nil
755
775
756
776
// Make sure we loop until all child tasks have completed
@@ -999,22 +1019,14 @@ public struct ThrowingTaskGroup<ChildTaskResult: Sendable, Failure: Error> {
999
1019
/// - Throws: The error thrown by the next child task that completes.
1000
1020
///
1001
1021
/// - SeeAlso: `nextResult()`
1002
- public mutating func next( ) async throws -> ChildTaskResult ? {
1022
+ public mutating func next( isolation : isolated ( any Actor ) ? = #isolation ) async throws -> ChildTaskResult ? {
1003
1023
return try await _taskGroupWaitNext ( group: _group)
1004
1024
}
1005
1025
1006
- @_silgen_name ( " $sScg10nextResults0B0Oyxq_GSgyYaKF " )
1007
1026
@usableFromInline
1008
- mutating func nextResultForABI( ) async throws -> Result < ChildTaskResult , Failure > ? {
1009
- do {
1010
- guard let success: ChildTaskResult = try await _taskGroupWaitNext ( group: _group) else {
1011
- return nil
1012
- }
1013
-
1014
- return . success( success)
1015
- } catch {
1016
- return . failure( error as! Failure ) // as!-safe, because we are only allowed to throw Failure (Error)
1017
- }
1027
+ @_silgen_name ( " $sScg4nextxSgyYaKF " )
1028
+ internal mutating func __abi_next( ) async throws -> ChildTaskResult ? {
1029
+ return try await _taskGroupWaitNext ( group: _group)
1018
1030
}
1019
1031
1020
1032
/// Wait for the next child task to complete,
@@ -1052,10 +1064,23 @@ public struct ThrowingTaskGroup<ChildTaskResult: Sendable, Failure: Error> {
1052
1064
///
1053
1065
/// - SeeAlso: `next()`
1054
1066
@_alwaysEmitIntoClient
1055
- public mutating func nextResult( ) async -> Result < ChildTaskResult , Failure > ? {
1056
- return try ! await nextResultForABI ( )
1067
+ public mutating func nextResult( isolation : isolated ( any Actor ) ? = #isolation ) async -> Result < ChildTaskResult , Failure > ? {
1068
+ return try ! await __abi_nextResult ( )
1057
1069
}
1058
1070
1071
+ @_silgen_name ( " $sScg10nextResults0B0Oyxq_GSgyYaKF " )
1072
+ @usableFromInline
1073
+ mutating func __abi_nextResult( ) async throws -> Result < ChildTaskResult , Failure > ? {
1074
+ do {
1075
+ guard let success: ChildTaskResult = try await _taskGroupWaitNext ( group: _group) else {
1076
+ return nil
1077
+ }
1078
+
1079
+ return . success( success)
1080
+ } catch {
1081
+ return . failure( error as! Failure ) // as!-safe, because we are only allowed to throw Failure (Error)
1082
+ }
1083
+ }
1059
1084
/// A Boolean value that indicates whether the group has any remaining tasks.
1060
1085
///
1061
1086
/// At the start of the body of a `withThrowingTaskGroup(of:returning:body:)` call,
0 commit comments