Skip to content

Commit

Permalink
Fix orderings in LocalPool waker (#2608)
Browse files Browse the repository at this point in the history
  • Loading branch information
ibraheemdev committed Jun 5, 2022
1 parent 556cc46 commit f57302d
Showing 1 changed file with 4 additions and 8 deletions.
12 changes: 4 additions & 8 deletions futures-executor/src/local_pool.rs
Expand Up @@ -63,7 +63,7 @@ thread_local! {
impl ArcWake for ThreadNotify {
fn wake_by_ref(arc_self: &Arc<Self>) {
// Make sure the wakeup is remembered until the next `park()`.
let unparked = arc_self.unparked.swap(true, Ordering::Relaxed);
let unparked = arc_self.unparked.swap(true, Ordering::Release);
if !unparked {
// If the thread has not been unparked yet, it must be done
// now. If it was actually parked, it will run again,
Expand All @@ -90,17 +90,13 @@ fn run_executor<T, F: FnMut(&mut Context<'_>) -> Poll<T>>(mut f: F) -> T {
if let Poll::Ready(t) = f(&mut cx) {
return t;
}
// Consume the wakeup that occurred while executing `f`, if any.
let unparked = thread_notify.unparked.swap(false, Ordering::Acquire);
if !unparked {

// Wait for a wakeup.
while !thread_notify.unparked.swap(false, Ordering::Acquire) {
// No wakeup occurred. It may occur now, right before parking,
// but in that case the token made available by `unpark()`
// is guaranteed to still be available and `park()` is a no-op.
thread::park();
// When the thread is unparked, `unparked` will have been set
// and needs to be unset before the next call to `f` to avoid
// a redundant loop iteration.
thread_notify.unparked.store(false, Ordering::Release);
}
}
})
Expand Down

0 comments on commit f57302d

Please sign in to comment.