@@ -390,7 +390,11 @@ class TaskGroupBase : public TaskGroupTaskStatusRecord {
390
390
virtual void enqueueCompletedTask (AsyncTask *completedTask, bool hadErrorResult) = 0;
391
391
392
392
// / Resume waiting task with result from `completedTask`
393
- void resumeWaitingTask (AsyncTask *completedTask, TaskGroupStatus &assumed, bool hadErrorResult, bool alreadyDecremented = false );
393
+ void resumeWaitingTask (AsyncTask *completedTask,
394
+ TaskGroupStatus &assumed,
395
+ bool hadErrorResult,
396
+ bool alreadyDecremented = false ,
397
+ bool taskWasRetained = false );
394
398
395
399
// ==== Status manipulation -------------------------------------------------
396
400
@@ -827,7 +831,9 @@ class DiscardingTaskGroup: public TaskGroupBase {
827
831
828
832
private:
829
833
// / Resume waiting task with specified error
830
- void resumeWaitingTaskWithError (SwiftError *error, TaskGroupStatus &assumed, bool alreadyDecremented);
834
+ void resumeWaitingTaskWithError (SwiftError *error,
835
+ TaskGroupStatus &assumed,
836
+ bool alreadyDecremented);
831
837
};
832
838
833
839
} // end anonymous namespace
@@ -1240,11 +1246,16 @@ void DiscardingTaskGroup::offer(AsyncTask *completedTask, AsyncContext *context)
1240
1246
switch (readyErrorItem.getStatus ()) {
1241
1247
case ReadyStatus::RawError:
1242
1248
SWIFT_TASK_GROUP_DEBUG_LOG (this , " offer, complete, resume with raw error:%p" , readyErrorItem.getRawError (this ));
1243
- resumeWaitingTaskWithError (readyErrorItem.getRawError (this ), assumed, alreadyDecrementedStatus);
1249
+ resumeWaitingTaskWithError (readyErrorItem.getRawError (this ), assumed,
1250
+ alreadyDecrementedStatus);
1244
1251
break ;
1245
1252
case ReadyStatus::Error:
1246
1253
SWIFT_TASK_GROUP_DEBUG_LOG (this , " offer, complete, resume with errorItem.task:%p" , readyErrorItem.getTask ());
1247
- resumeWaitingTask (readyErrorItem.getTask (), assumed, /* hadErrorResult=*/ true , alreadyDecrementedStatus);
1254
+ SWIFT_TASK_GROUP_DEBUG_LOG (this , " offer, complete, expect that it was extra retained %p" , readyErrorItem.getTask ());
1255
+ resumeWaitingTask (readyErrorItem.getTask (), assumed,
1256
+ /* hadErrorResult=*/ true ,
1257
+ alreadyDecrementedStatus,
1258
+ /* taskWasRetained=*/ true );
1248
1259
break ;
1249
1260
default :
1250
1261
swift_Concurrency_fatalError (0 ,
@@ -1283,7 +1294,10 @@ void DiscardingTaskGroup::offer(AsyncTask *completedTask, AsyncContext *context)
1283
1294
resumeWaitingTaskWithError (readyErrorItem.getRawError (this ), assumed, alreadyDecrementedStatus);
1284
1295
break ;
1285
1296
case ReadyStatus::Error:
1286
- resumeWaitingTask (readyErrorItem.getTask (), assumed, /* hadErrorResult=*/ true , alreadyDecrementedStatus);
1297
+ resumeWaitingTask (readyErrorItem.getTask (), assumed,
1298
+ /* hadErrorResult=*/ true ,
1299
+ alreadyDecrementedStatus,
1300
+ /* taskWasRetained=*/ true );
1287
1301
break ;
1288
1302
default :
1289
1303
swift_Concurrency_fatalError (0 ,
@@ -1317,7 +1331,8 @@ void TaskGroupBase::resumeWaitingTask(
1317
1331
AsyncTask *completedTask,
1318
1332
TaskGroupStatus &assumed,
1319
1333
bool hadErrorResult,
1320
- bool alreadyDecremented) {
1334
+ bool alreadyDecremented,
1335
+ bool taskWasRetained) {
1321
1336
auto waitingTask = waitQueue.load (std::memory_order_acquire);
1322
1337
assert (waitingTask && " waitingTask must not be null when attempting to resume it" );
1323
1338
assert (assumed.hasWaitingTask ());
@@ -1384,13 +1399,21 @@ void TaskGroupBase::resumeWaitingTask(
1384
1399
auto before = completedTask;
1385
1400
_swift_taskGroup_detachChild (asAbstract (this ), completedTask);
1386
1401
SWIFT_TASK_GROUP_DEBUG_LOG (this , " completedTask %p; AFTER DETACH (count:%d)" , completedTask, swift_retainCount (completedTask));
1387
- if (isDiscardingResults () && hadErrorResult) {
1402
+ if (isDiscardingResults () && hadErrorResult && taskWasRetained ) {
1388
1403
SWIFT_TASK_GROUP_DEBUG_LOG (this , " BEFORE RELEASE error task=%p (count:%d)\n " ,
1389
1404
completedTask,
1390
1405
swift_retainCount (completedTask));
1391
- // We only used the task to keep the error in the future fragment around
1406
+ // We only used the task to keep the error in the future fragment around
1392
1407
// so now that we emitted the error and detached the task, we are free to release the task immediately.
1393
- swift_release (completedTask); // we need to do this if the error is a class
1408
+ auto error = completedTask->futureFragment ()->getError ();
1409
+ fprintf (stderr, " [%s:%d](%s) THE ERRROR IN RELEASING %p\n " , __FILE_NAME__, __LINE__, __FUNCTION__,
1410
+ error);
1411
+ swift_release (completedTask);
1412
+ // swift_errorRelease(error);
1413
+ } else {
1414
+ fprintf (stderr, " [%s:%d](%s) DID NOT RELEASE %p\n " , __FILE_NAME__, __LINE__, __FUNCTION__,
1415
+ completedTask);
1416
+ // assert(false);
1394
1417
}
1395
1418
1396
1419
_swift_tsan_acquire (static_cast <Job *>(waitingTask));
@@ -1799,6 +1822,7 @@ void TaskGroupBase::waitAll(SwiftError* bodyError, AsyncTask *waitingTask,
1799
1822
1800
1823
#if SWIFT_TASK_GROUP_BODY_THROWN_ERROR_WINS
1801
1824
if (bodyError) {
1825
+ // FIXME: are we ok with releases here?
1802
1826
fillGroupNextErrorResult (context, bodyError);
1803
1827
} else {
1804
1828
fillGroupNextResult (context, result);
0 commit comments