65
65
using namespace swift ;
66
66
67
67
#if 0
68
+ #define SWIFT_TASK_GROUP_DEBUG_LOG_ENABLED 1
68
69
#define SWIFT_TASK_GROUP_DEBUG_LOG(group, fmt, ...) \
69
70
fprintf(stderr, "[%#lx] [%s:%d][group(%p%s)] (%s) " fmt "\n", \
70
71
(unsigned long)Thread::current().platformThreadId(), \
@@ -81,6 +82,7 @@ fprintf(stderr, "[%#lx] [%s:%d][group(%p)] (%s) " fmt "\n", \
81
82
__FUNCTION__, \
82
83
__VA_ARGS__)
83
84
#else
85
+ #define SWIFT_TASK_GROUP_DEBUG_LOG_ENABLED 0
84
86
#define SWIFT_TASK_GROUP_DEBUG_LOG (group, fmt, ...) (void )0
85
87
#define SWIFT_TASK_GROUP_DEBUG_LOG_0 (group, fmt, ...) (void )0
86
88
#endif
@@ -941,7 +943,7 @@ static void swift_taskGroup_initializeWithFlagsImpl(size_t rawGroupFlags,
941
943
// ==== child task management --------------------------------------------------
942
944
943
945
void TaskGroup::addChildTask (AsyncTask *child) {
944
- SWIFT_TASK_DEBUG_LOG ( " attach child task = %p to group = %p " , child, this );
946
+ SWIFT_TASK_GROUP_DEBUG_LOG ( this , " attach child task = %p" , child);
945
947
946
948
// Add the child task to this task group. The corresponding removal
947
949
// won't happen until the parent task successfully polls for this child
@@ -959,7 +961,7 @@ void TaskGroup::addChildTask(AsyncTask *child) {
959
961
}
960
962
961
963
void TaskGroup::removeChildTask (AsyncTask *child) {
962
- SWIFT_TASK_DEBUG_LOG ( " detach child task = %p from group = %p " , child, this );
964
+ SWIFT_TASK_GROUP_DEBUG_LOG ( this , " detach child task = %p" , child);
963
965
964
966
auto groupRecord = asBaseImpl (this )->getTaskRecord ();
965
967
@@ -979,7 +981,7 @@ static void swift_taskGroup_destroyImpl(TaskGroup *group) {
979
981
}
980
982
981
983
void AccumulatingTaskGroup::destroy () {
982
- #if SWIFT_TASK_DEBUG_LOG_ENABLED
984
+ #if SWIFT_TASK_GROUP_DEBUG_LOG_ENABLED
983
985
if (!this ->isEmpty ()) {
984
986
auto status = this ->statusLoadRelaxed ();
985
987
SWIFT_TASK_GROUP_DEBUG_LOG (this , " destroy, tasks .ready = %d, .pending = %llu" ,
@@ -988,7 +990,10 @@ void AccumulatingTaskGroup::destroy() {
988
990
SWIFT_TASK_DEBUG_LOG (" destroying task group = %p" , this );
989
991
}
990
992
#endif
993
+ // Verify using the group's status that indeed we're expected to be empty
991
994
assert (this ->isEmpty () && " Attempted to destroy non-empty task group!" );
995
+ // Double check by inspecting the group record, it should contain no children
996
+ assert (getTaskRecord ()->getFirstChild () == nullptr && " Task group record still has child task!" );
992
997
993
998
// First, remove the group from the task and deallocate the record
994
999
removeStatusRecordFromSelf (getTaskRecord ());
@@ -1002,7 +1007,7 @@ void AccumulatingTaskGroup::destroy() {
1002
1007
}
1003
1008
1004
1009
void DiscardingTaskGroup::destroy () {
1005
- #if SWIFT_TASK_DEBUG_LOG_ENABLED
1010
+ #if SWIFT_TASK_GROUP_DEBUG_LOG_ENABLED
1006
1011
if (!this ->isEmpty ()) {
1007
1012
auto status = this ->statusLoadRelaxed ();
1008
1013
SWIFT_TASK_GROUP_DEBUG_LOG (this , " destroy, tasks .ready = %d, .pending = %llu" ,
@@ -1011,7 +1016,10 @@ void DiscardingTaskGroup::destroy() {
1011
1016
SWIFT_TASK_DEBUG_LOG (" destroying discarding task group = %p" , this );
1012
1017
}
1013
1018
#endif
1019
+ // Verify using the group's status that indeed we're expected to be empty
1014
1020
assert (this ->isEmpty () && " Attempted to destroy non-empty task group!" );
1021
+ // Double check by inspecting the group record, it should contain no children
1022
+ assert (getTaskRecord ()->getFirstChild () == nullptr && " Task group record still has child task!" );
1015
1023
1016
1024
// First, remove the group from the task and deallocate the record
1017
1025
removeStatusRecordFromSelf (getTaskRecord ());
@@ -1249,7 +1257,12 @@ void DiscardingTaskGroup::offer(AsyncTask *completedTask, AsyncContext *context)
1249
1257
alreadyDecrementedStatus);
1250
1258
break ;
1251
1259
case ReadyStatus::Error:
1252
- SWIFT_TASK_GROUP_DEBUG_LOG (this , " offer, complete, resume with errorItem.task:%p" , readyErrorItem.getTask ());
1260
+ // The completed task failed, but we already stored a different failed task.
1261
+ // Thus we discard this error and complete with the previously stored.
1262
+ SWIFT_TASK_GROUP_DEBUG_LOG (this , " offer, complete, discard error completedTask %p, resume with errorItem.task:%p" ,
1263
+ completedTask,
1264
+ readyErrorItem.getTask ());
1265
+ _swift_taskGroup_detachChild (asAbstract (this ), completedTask);
1253
1266
resumeWaitingTask (readyErrorItem.getTask (), assumed,
1254
1267
/* hadErrorResult=*/ true ,
1255
1268
alreadyDecrementedStatus,
0 commit comments