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