Skip to content

Commit 1195955

Browse files
committed
Review feedback: add better code comments
1 parent 8aa70dc commit 1195955

File tree

1 file changed

+42
-10
lines changed

1 file changed

+42
-10
lines changed

stdlib/public/Concurrency/TaskGroup.cpp

+42-10
Original file line numberDiff line numberDiff line change
@@ -1238,7 +1238,11 @@ void AccumulatingTaskGroup::offer(AsyncTask *completedTask, AsyncContext *contex
12381238
auto prepared = prepareWaitingTaskWithTask(
12391239
/*complete=*/waitingTask, /*with=*/completedTask,
12401240
assumed, hadErrorResult);
1241-
unlock(); // we MUST unlock before running the waiting task
1241+
// we must unlock before running the waiting task,
1242+
// in order to avoid the potential for the resumed task
1243+
// to cause a group destroy, in which case the unlock might
1244+
// attempt memory in an invalid state.
1245+
unlock();
12421246
return runWaitingTask(prepared);
12431247
} else {
12441248
// ==== b) enqueue completion ------------------------------------------------
@@ -1314,7 +1318,11 @@ void DiscardingTaskGroup::offer(AsyncTask *completedTask, AsyncContext *context)
13141318
/*complete=*/waitingTask,
13151319
/*with=*/readyErrorItem.getRawError(this), assumed,
13161320
alreadyDecrementedStatus);
1317-
unlock(); // we MUST unlock before running the waiting task
1321+
// we must unlock before running the waiting task,
1322+
// in order to avoid the potential for the resumed task
1323+
// to cause a group destroy, in which case the unlock might
1324+
// attempt memory in an invalid state.
1325+
unlock();
13181326
return runWaitingTask(prepared);
13191327
}
13201328
case ReadyStatus::Error: {
@@ -1331,7 +1339,11 @@ void DiscardingTaskGroup::offer(AsyncTask *completedTask, AsyncContext *context)
13311339
/*with=*/readyErrorItem.getTask(), assumed,
13321340
/*hadErrorResult=*/true, alreadyDecrementedStatus,
13331341
/*taskWasRetained=*/true);
1334-
unlock(); // we MUST unlock before running the waiting task
1342+
// we must unlock before running the waiting task,
1343+
// in order to avoid the potential for the resumed task
1344+
// to cause a group destroy, in which case the unlock might
1345+
// attempt memory in an invalid state.
1346+
unlock();
13351347
return runWaitingTask(prepared);
13361348
}
13371349
default: {
@@ -1348,7 +1360,11 @@ void DiscardingTaskGroup::offer(AsyncTask *completedTask, AsyncContext *context)
13481360
// There was no prior failed task stored, so we should resume the waitingTask with this (failed) completedTask
13491361
auto prepared = prepareWaitingTaskWithTask(/*complete=*/waitingTask, /*with=*/completedTask,
13501362
assumed, hadErrorResult, alreadyDecrementedStatus);
1351-
unlock(); // we MUST unlock before running the waiting task
1363+
// we must unlock before running the waiting task,
1364+
// in order to avoid the potential for the resumed task
1365+
// to cause a group destroy, in which case the unlock might
1366+
// attempt memory in an invalid state.
1367+
unlock();
13521368
return runWaitingTask(prepared);
13531369
}
13541370
} else if (readyQueue.isEmpty()) {
@@ -1370,7 +1386,7 @@ void DiscardingTaskGroup::offer(AsyncTask *completedTask, AsyncContext *context)
13701386
// We grab the waiting task while holding the group lock, because this
13711387
// allows a single task to get the waiting task and attempt to complete it.
13721388
// As another offer gets to run, it will have either a different waiting task, or no waiting task at all.
1373-
auto waitingTask = waitQueue.load(std::memory_order_acquire);
1389+
auto waitingTask = waitQueue.load(std::memory_order_acquire);
13741390
if (!waitQueue.compare_exchange_strong(waitingTask, nullptr)) {
13751391
swift_Concurrency_fatalError(0, "Failed to claim waitingTask!");
13761392
}
@@ -1391,7 +1407,11 @@ void DiscardingTaskGroup::offer(AsyncTask *completedTask, AsyncContext *context)
13911407
auto task = prepareWaitingTaskWithError(
13921408
/*complete=*/waitingTask, /*with=*/readyErrorItem.getRawError(this),
13931409
assumed, alreadyDecrementedStatus);
1394-
unlock(); // we MUST unlock before running the waiting task
1410+
// we must unlock before running the waiting task,
1411+
// in order to avoid the potential for the resumed task
1412+
// to cause a group destroy, in which case the unlock might
1413+
// attempt memory in an invalid state.
1414+
unlock();
13951415
return runWaitingTask(task);
13961416
}
13971417
case ReadyStatus::Error: {
@@ -1400,7 +1420,11 @@ void DiscardingTaskGroup::offer(AsyncTask *completedTask, AsyncContext *context)
14001420
/*with=*/readyErrorItem.getTask(), assumed,
14011421
/*hadErrorResult=*/true, alreadyDecrementedStatus,
14021422
/*taskWasRetained=*/true);
1403-
unlock(); // we MUST unlock before running the waiting task
1423+
// we must unlock before running the waiting task,
1424+
// in order to avoid the potential for the resumed task
1425+
// to cause a group destroy, in which case the unlock might
1426+
// attempt memory in an invalid state.
1427+
unlock();
14041428
return runWaitingTask(preparedWaitingTask);
14051429
}
14061430
default: {
@@ -1415,7 +1439,11 @@ void DiscardingTaskGroup::offer(AsyncTask *completedTask, AsyncContext *context)
14151439
auto prepared = prepareWaitingTaskWithTask(
14161440
/*complete=*/waitingTask, /*with=*/completedTask,
14171441
assumed, /*hadErrorResult=*/false, alreadyDecrementedStatus);
1418-
unlock(); // we MUST unlock before running the waiting task
1442+
// we must unlock before running the waiting task,
1443+
// in order to avoid the potential for the resumed task
1444+
// to cause a group destroy, in which case the unlock might
1445+
// attempt memory in an invalid state.
1446+
unlock();
14191447
return runWaitingTask(prepared);
14201448
}
14211449
} else {
@@ -1459,7 +1487,7 @@ TaskGroupBase::PreparedWaitingTask TaskGroupBase::prepareWaitingTaskWithTask(
14591487
(void) statusCompletePendingReadyWaiting(assumed);
14601488
}
14611489

1462-
// Run the task.
1490+
// Populate the waiting task with value from completedTask.
14631491
auto result = PollResult::get(completedTask, hadErrorResult);
14641492
SWIFT_TASK_GROUP_DEBUG_LOG(this,
14651493
"resume waiting DONE, task = %p, error:%d, complete with = %p, status = %s",
@@ -1759,7 +1787,11 @@ reevaluate_if_taskgroup_has_results:;
17591787
waitHead, waitingTask,
17601788
/*success*/ std::memory_order_release,
17611789
/*failure*/ std::memory_order_acquire)) {
1762-
unlock(); // TODO: remove fragment lock, and use status for synchronization
1790+
// we must unlock before running the waiting task,
1791+
// in order to avoid the potential for the resumed task
1792+
// to cause a group destroy, in which case the unlock might
1793+
// attempt memory in an invalid state.
1794+
unlock();
17631795
#if SWIFT_CONCURRENCY_TASK_TO_THREAD_MODEL
17641796
// The logic here is paired with the logic in TaskGroupBase::offer. Once
17651797
// we run the

0 commit comments

Comments
 (0)