@@ -114,6 +114,7 @@ FutureFragment::Status AsyncTask::waitFuture(AsyncTask *waitingTask,
114
114
assert (isFuture ());
115
115
auto fragment = futureFragment ();
116
116
117
+ // NOTE: this acquire synchronizes with `completeFuture`.
117
118
auto queueHead = fragment->waitQueue .load (std::memory_order_acquire);
118
119
bool contextInitialized = false ;
119
120
auto escalatedPriority = JobPriority::Unspecified;
@@ -214,6 +215,7 @@ FutureFragment::Status AsyncTask::waitFuture(AsyncTask *waitingTask,
214
215
continue ;
215
216
#else
216
217
// Put the waiting task at the beginning of the wait queue.
218
+ // NOTE: this acquire-release synchronizes with `completeFuture`.
217
219
waitingTask->getNextWaitingTask () = queueHead.getTask ();
218
220
auto newQueueHead = WaitQueueItem::get (Status::Executing, waitingTask);
219
221
if (fragment->waitQueue .compare_exchange_weak (
@@ -267,8 +269,10 @@ void AsyncTask::completeFuture(AsyncContext *context) {
267
269
hadErrorResult ? Status::Error : Status::Success,
268
270
nullptr
269
271
);
272
+
273
+ // NOTE: this acquire-release synchronizes with `waitFuture`.
270
274
auto queueHead = fragment->waitQueue .exchange (
271
- newQueueHead, std::memory_order_acquire );
275
+ newQueueHead, std::memory_order_acq_rel );
272
276
assert (queueHead.getStatus () == Status::Executing);
273
277
274
278
// If this is task group child, notify the parent group about the completion.
0 commit comments