@@ -473,9 +473,8 @@ class TaskGroupBase : public TaskGroupTaskStatusRecord {
473473 bool statusCancel ();
474474
475475 // / 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);
479478};
480479
481480#if !SWIFT_CONCURRENCY_EMBEDDED
@@ -1370,7 +1369,8 @@ void DiscardingTaskGroup::offer(AsyncTask *completedTask, AsyncContext *context)
13701369 // Discarding results mode immediately treats a child failure as group cancellation.
13711370 // "All for one, one for all!" - any task failing must cause the group and all sibling tasks to be cancelled,
13721371 // such that the discarding group can exit as soon as possible.
1373- cancelAll ();
1372+ auto parent = completedTask->childFragment ()->getParent ();
1373+ cancelAll (parent);
13741374
13751375 if (afterComplete.hasWaitingTask () && afterComplete.pendingTasks (this ) == 0 ) {
13761376 // We grab the waiting task while holding the group lock, because this
@@ -2089,10 +2089,12 @@ static bool swift_taskGroup_isCancelledImpl(TaskGroup *group) {
20892089
20902090SWIFT_CC (swift)
20912091static 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 ());
20932095}
20942096
2095- bool TaskGroupBase::cancelAll () {
2097+ bool TaskGroupBase::cancelAll (AsyncTask *owningTask ) {
20962098 SWIFT_TASK_DEBUG_LOG (" cancel all tasks in group = %p" , this );
20972099
20982100 // Flag the task group itself as cancelled. If this was already
@@ -2106,8 +2108,8 @@ bool TaskGroupBase::cancelAll() {
21062108
21072109 // Cancel all the child tasks. TaskGroup is not a Sendable type,
21082110 // 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 );
21112113
21122114 return true ;
21132115}
@@ -2116,22 +2118,8 @@ SWIFT_CC(swift)
21162118static void swift_task_cancel_group_child_tasksImpl(TaskGroup *group) {
21172119 // TaskGroup is not a Sendable type, and so this operation (which is not
21182120 // 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 ());
21352123}
21362124
21372125// =============================================================================
0 commit comments