@@ -780,8 +780,15 @@ void swift::_swift_taskGroup_detachChild(TaskGroup *group,
780
780
// /
781
781
// / The caller must guarantee that this is called while holding the owning
782
782
// / task's status record lock.
783
- void swift::_swift_taskGroup_cancelAllChildren (TaskGroup *group) {
784
- assert (group->isCancelled () && " Expected task group to be cancelled when cancelling all child tasks." );
783
+ void swift::_swift_taskGroup_cancel (TaskGroup *group) {
784
+ // If the task group was already cancelled, we don't need to traverse children
785
+ // again; they already were all cancelled, or if new ones will be added, they
786
+ // will be added with the cancelled status set immediately.
787
+ bool alreadyCancelled = group->statusCancel ();
788
+ if (alreadyCancelled) {
789
+ return ;
790
+ }
791
+
785
792
// Because only the owning task of the task group can modify the
786
793
// child list of a task group status record, and it can only do so
787
794
// while holding the owning task's status record lock, we do not need
@@ -793,7 +800,7 @@ void swift::_swift_taskGroup_cancelAllChildren(TaskGroup *group) {
793
800
// / Cancel all the child tasks that belong to `group`.
794
801
// /
795
802
// / The caller must guarantee that this is called from the owning task.
796
- void swift::_swift_taskGroup_cancelAllChildren_unlocked (TaskGroup *group,
803
+ void swift::_swift_taskGroup_cancel_unlocked (TaskGroup *group,
797
804
AsyncTask *owningTask) {
798
805
// Early out. If there are no children, there's nothing to do. We can safely
799
806
// check this without locking, since this can only be concurrently mutated
@@ -802,7 +809,7 @@ void swift::_swift_taskGroup_cancelAllChildren_unlocked(TaskGroup *group,
802
809
return ;
803
810
804
811
withStatusRecordLock (owningTask, [&group](ActiveTaskStatus status) {
805
- _swift_taskGroup_cancelAllChildren (group);
812
+ _swift_taskGroup_cancel (group);
806
813
});
807
814
}
808
815
@@ -826,12 +833,7 @@ static void performCancellationAction(TaskStatusRecord *record) {
826
833
// under the synchronous control of the task that owns the group.
827
834
case TaskStatusRecordKind::TaskGroup: {
828
835
auto groupRecord = cast<TaskGroupTaskStatusRecord>(record);
829
- auto group = groupRecord->getGroup ();
830
- auto wasAlreadyCancelled = group->statusCancel ();
831
- if (wasAlreadyCancelled) {
832
- return ;
833
- }
834
- _swift_taskGroup_cancelAllChildren (group);
836
+ _swift_taskGroup_cancel (groupRecord->getGroup ());
835
837
return ;
836
838
}
837
839
0 commit comments