@@ -473,9 +473,8 @@ class TaskGroupBase : public TaskGroupTaskStatusRecord {
473
473
bool statusCancel ();
474
474
475
475
// / Cancel the group and all of its child tasks recursively.
476
- // / This also sets
477
- bool cancelAll ();
478
-
476
+ // / This also sets the cancelled bit in the group status.
477
+ bool cancelAll (AsyncTask *task);
479
478
};
480
479
481
480
#if !SWIFT_CONCURRENCY_EMBEDDED
@@ -1370,7 +1369,8 @@ void DiscardingTaskGroup::offer(AsyncTask *completedTask, AsyncContext *context)
1370
1369
// Discarding results mode immediately treats a child failure as group cancellation.
1371
1370
// "All for one, one for all!" - any task failing must cause the group and all sibling tasks to be cancelled,
1372
1371
// such that the discarding group can exit as soon as possible.
1373
- cancelAll ();
1372
+ auto parent = completedTask->childFragment ()->getParent ();
1373
+ cancelAll (parent);
1374
1374
1375
1375
if (afterComplete.hasWaitingTask () && afterComplete.pendingTasks (this ) == 0 ) {
1376
1376
// We grab the waiting task while holding the group lock, because this
@@ -2089,10 +2089,12 @@ static bool swift_taskGroup_isCancelledImpl(TaskGroup *group) {
2089
2089
2090
2090
SWIFT_CC (swift)
2091
2091
static void swift_taskGroup_cancelAllImpl(TaskGroup *group) {
2092
- asBaseImpl (group)->cancelAll ();
2092
+ // TaskGroup is not a Sendable type, so this can only be called from the
2093
+ // owning task.
2094
+ asBaseImpl (group)->cancelAll (swift_task_getCurrent ());
2093
2095
}
2094
2096
2095
- bool TaskGroupBase::cancelAll () {
2097
+ bool TaskGroupBase::cancelAll (AsyncTask *owningTask ) {
2096
2098
SWIFT_TASK_DEBUG_LOG (" cancel all tasks in group = %p" , this );
2097
2099
2098
2100
// Flag the task group itself as cancelled. If this was already
@@ -2106,8 +2108,8 @@ bool TaskGroupBase::cancelAll() {
2106
2108
2107
2109
// Cancel all the child tasks. TaskGroup is not a Sendable type,
2108
2110
// so cancelAll() can only be called from the owning task. This
2109
- // satisfies the precondition on cancelAllChildren ().
2110
- _swift_taskGroup_cancelAllChildren (asAbstract (this ));
2111
+ // satisfies the precondition on cancelAllChildren_unlocked ().
2112
+ _swift_taskGroup_cancelAllChildren_unlocked (asAbstract (this ), owningTask );
2111
2113
2112
2114
return true ;
2113
2115
}
@@ -2116,22 +2118,8 @@ SWIFT_CC(swift)
2116
2118
static void swift_task_cancel_group_child_tasksImpl(TaskGroup *group) {
2117
2119
// TaskGroup is not a Sendable type, and so this operation (which is not
2118
2120
// currently exposed in the API) can only be called from the owning
2119
- // task. This satisfies the precondition on cancelAllChildren().
2120
- _swift_taskGroup_cancelAllChildren (group);
2121
- }
2122
-
2123
- // / Cancel all the children of the given task group.
2124
- // /
2125
- // / The caller must guarantee that this is either called from the
2126
- // / owning task of the task group or while holding the owning task's
2127
- // / status record lock.
2128
- void swift::_swift_taskGroup_cancelAllChildren (TaskGroup *group) {
2129
- // Because only the owning task of the task group can modify the
2130
- // child list of a task group status record, and it can only do so
2131
- // while holding the owning task's status record lock, we do not need
2132
- // any additional synchronization within this function.
2133
- for (auto childTask: group->getTaskRecord ()->children ())
2134
- swift_task_cancel (childTask);
2121
+ // task. This satisfies the precondition on cancelAllChildren_unlocked().
2122
+ _swift_taskGroup_cancelAllChildren_unlocked (group, swift_task_getCurrent ());
2135
2123
}
2136
2124
2137
2125
// =============================================================================
0 commit comments