@@ -474,9 +474,8 @@ class TaskGroupBase : public TaskGroupTaskStatusRecord {
474474 bool statusCancel ();
475475
476476 // / 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);
480479};
481480
482481#if !SWIFT_CONCURRENCY_EMBEDDED
@@ -1378,7 +1377,8 @@ void DiscardingTaskGroup::offer(AsyncTask *completedTask, AsyncContext *context)
13781377 // Discarding results mode immediately treats a child failure as group cancellation.
13791378 // "All for one, one for all!" - any task failing must cause the group and all sibling tasks to be cancelled,
13801379 // such that the discarding group can exit as soon as possible.
1381- cancelAll ();
1380+ auto parent = completedTask->childFragment ()->getParent ();
1381+ cancelAll (parent);
13821382
13831383 if (afterComplete.hasWaitingTask () && afterComplete.pendingTasks (this ) == 0 ) {
13841384 // We grab the waiting task while holding the group lock, because this
@@ -2097,10 +2097,12 @@ static bool swift_taskGroup_isCancelledImpl(TaskGroup *group) {
20972097
20982098SWIFT_CC (swift)
20992099static 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 ());
21012103}
21022104
2103- bool TaskGroupBase::cancelAll () {
2105+ bool TaskGroupBase::cancelAll (AsyncTask *owningTask ) {
21042106 SWIFT_TASK_DEBUG_LOG (" cancel all tasks in group = %p" , this );
21052107
21062108 // Flag the task group itself as cancelled. If this was already
@@ -2114,8 +2116,8 @@ bool TaskGroupBase::cancelAll() {
21142116
21152117 // Cancel all the child tasks. TaskGroup is not a Sendable type,
21162118 // 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 );
21192121
21202122 return true ;
21212123}
@@ -2124,22 +2126,8 @@ SWIFT_CC(swift)
21242126static void swift_task_cancel_group_child_tasksImpl(TaskGroup *group) {
21252127 // TaskGroup is not a Sendable type, and so this operation (which is not
21262128 // 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 ());
21432131}
21442132
21452133// =============================================================================
0 commit comments