Skip to content

Commit 7786e7d

Browse files
ibraheemdevtaiki-e
authored andcommitted
Fix orderings in LocalPool waker (#2608)
1 parent 69ea267 commit 7786e7d

File tree

1 file changed

+4
-8
lines changed

1 file changed

+4
-8
lines changed

futures-executor/src/local_pool.rs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ thread_local! {
6363
impl ArcWake for ThreadNotify {
6464
fn wake_by_ref(arc_self: &Arc<Self>) {
6565
// Make sure the wakeup is remembered until the next `park()`.
66-
let unparked = arc_self.unparked.swap(true, Ordering::Relaxed);
66+
let unparked = arc_self.unparked.swap(true, Ordering::Release);
6767
if !unparked {
6868
// If the thread has not been unparked yet, it must be done
6969
// now. If it was actually parked, it will run again,
@@ -90,17 +90,13 @@ fn run_executor<T, F: FnMut(&mut Context<'_>) -> Poll<T>>(mut f: F) -> T {
9090
if let Poll::Ready(t) = f(&mut cx) {
9191
return t;
9292
}
93-
// Consume the wakeup that occurred while executing `f`, if any.
94-
let unparked = thread_notify.unparked.swap(false, Ordering::Acquire);
95-
if !unparked {
93+
94+
// Wait for a wakeup.
95+
while !thread_notify.unparked.swap(false, Ordering::Acquire) {
9696
// No wakeup occurred. It may occur now, right before parking,
9797
// but in that case the token made available by `unpark()`
9898
// is guaranteed to still be available and `park()` is a no-op.
9999
thread::park();
100-
// When the thread is unparked, `unparked` will have been set
101-
// and needs to be unset before the next call to `f` to avoid
102-
// a redundant loop iteration.
103-
thread_notify.unparked.store(false, Ordering::Release);
104100
}
105101
}
106102
})

0 commit comments

Comments
 (0)