@@ -92,8 +92,6 @@ void AsyncTask::completeFuture(AsyncContext *context, ExecutorRef executor) {
92
92
using Status = FutureFragment::Status;
93
93
using WaitQueueItem = FutureFragment::WaitQueueItem;
94
94
95
- _swift_tsan_release (static_cast <Job *>(this ));
96
-
97
95
assert (isFuture ());
98
96
auto fragment = futureFragment ();
99
97
@@ -105,6 +103,8 @@ void AsyncTask::completeFuture(AsyncContext *context, ExecutorRef executor) {
105
103
hadErrorResult = true ;
106
104
}
107
105
106
+ _swift_tsan_release (static_cast <Job *>(this ));
107
+
108
108
// Update the status to signal completion.
109
109
auto newQueueHead = WaitQueueItem::get (
110
110
hadErrorResult ? Status::Error : Status::Success,
@@ -125,8 +125,6 @@ void AsyncTask::completeFuture(AsyncContext *context, ExecutorRef executor) {
125
125
// Schedule every waiting task on the executor.
126
126
auto waitingTask = queueHead.getTask ();
127
127
while (waitingTask) {
128
- _swift_tsan_acquire (static_cast <Job *>(waitingTask));
129
-
130
128
// Find the next waiting task before we invalidate it by resuming
131
129
// the task.
132
130
auto nextWaitingTask = waitingTask->getNextWaitingTask ();
@@ -140,6 +138,8 @@ void AsyncTask::completeFuture(AsyncContext *context, ExecutorRef executor) {
140
138
waitingContext->fillWithSuccess (fragment);
141
139
}
142
140
141
+ _swift_tsan_acquire (static_cast <Job *>(waitingTask));
142
+
143
143
// Enqueue the waiter on the global executor.
144
144
// TODO: allow waiters to fill in a suggested executor
145
145
swift_task_enqueueGlobal (waitingTask);
0 commit comments