64
64
65
65
using namespace swift ;
66
66
67
- #if 1
67
+ #if 0
68
68
#define SWIFT_TASK_GROUP_DEBUG_LOG(group, fmt, ...) \
69
69
fprintf(stderr, "[%#lx] [%s:%d][group(%p%s)] (%s) " fmt "\n", \
70
70
(unsigned long)Thread::current().platformThreadId(), \
@@ -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
@@ -1040,7 +1046,7 @@ static void fillGroupNextResult(TaskFutureWaitAsyncContext *context,
1040
1046
1041
1047
case PollStatus::Error: {
1042
1048
auto error = reinterpret_cast <SwiftError *>(result.storage );
1043
- fillGroupNextErrorResult (context, error); // FIXME: this specifically retains the error, but likely should not!??!!?
1049
+ fillGroupNextErrorResult (context, error);
1044
1050
return ;
1045
1051
}
1046
1052
@@ -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 ,
@@ -1293,14 +1307,6 @@ void DiscardingTaskGroup::offer(AsyncTask *completedTask, AsyncContext *context)
1293
1307
// This is the last task, we have a waiting task and there was no error stored previously;
1294
1308
// We must resume the waiting task with a success, so let us return here.
1295
1309
resumeWaitingTask (completedTask, assumed, /* hadErrorResult=*/ false , alreadyDecrementedStatus);
1296
-
1297
- // // TODO: since the DiscardingTaskGroup ended up written as `-> T` in order to use the same pointer auth as the
1298
- // // usual task closures; we end up retaining the value when it is returned. As this is a discarding group
1299
- // // we actually can and should release this value.
1300
- // // Is there a way we could avoid the retain made on the returned value entirely?
1301
- // if (completedTask->futureFragment()->getResultType()->isClassObject()) {
1302
- // swift_release(reinterpret_cast<HeapObject *>(completedTask->futureFragment()->getStoragePtr()));
1303
- // }
1304
1310
}
1305
1311
} else {
1306
1312
// it wasn't the last pending task, and there is no-one to resume;
@@ -1317,7 +1323,8 @@ void TaskGroupBase::resumeWaitingTask(
1317
1323
AsyncTask *completedTask,
1318
1324
TaskGroupStatus &assumed,
1319
1325
bool hadErrorResult,
1320
- bool alreadyDecremented) {
1326
+ bool alreadyDecremented,
1327
+ bool taskWasRetained) {
1321
1328
auto waitingTask = waitQueue.load (std::memory_order_acquire);
1322
1329
assert (waitingTask && " waitingTask must not be null when attempting to resume it" );
1323
1330
assert (assumed.hasWaitingTask ());
@@ -1384,14 +1391,14 @@ void TaskGroupBase::resumeWaitingTask(
1384
1391
auto before = completedTask;
1385
1392
_swift_taskGroup_detachChild (asAbstract (this ), completedTask);
1386
1393
SWIFT_TASK_GROUP_DEBUG_LOG (this , " completedTask %p; AFTER DETACH (count:%d)" , completedTask, swift_retainCount (completedTask));
1387
- if (hadErrorResult) {
1394
+ if (isDiscardingResults () && hadErrorResult && taskWasRetained ) {
1388
1395
SWIFT_TASK_GROUP_DEBUG_LOG (this , " BEFORE RELEASE error task=%p (count:%d)\n " ,
1389
1396
completedTask,
1390
1397
swift_retainCount (completedTask));
1391
1398
// We only used the task to keep the error in the future fragment around
1392
1399
// so now that we emitted the error and detached the task, we are free to release the task immediately.
1393
- auto error = reinterpret_cast <SwiftError *>(result. storage );
1394
- swift_release (completedTask); // we need to do this if the error is a class
1400
+ auto error = completedTask-> futureFragment ()-> getError ( );
1401
+ swift_release (completedTask);
1395
1402
}
1396
1403
1397
1404
_swift_tsan_acquire (static_cast <Job *>(waitingTask));
0 commit comments