AtomicWaker cleanups: cas + swap instead of loop cas
@@ -211,25 +211,11 @@ impl AtomicWaker {
//
// Start by assuming that the state is `REGISTERING` as this
// is what we jut set it to.
- let mut curr = REGISTERING;
-
- // If a task has to be woken, the waker will be set here.
- let mut wake_now: Option<Waker> = None;
-
- loop {
let res = self.state.compare_exchange(
- curr, WAITING, AcqRel, Acquire);
+ REGISTERING, WAITING, AcqRel, Acquire);
match res {
- Ok(_) => {
- // The atomic exchange was successful, now
- // wake the task (if set) and return.
- if let Some(waker) = wake_now {
- waker.wake();
- }
-
- return;
- }
+ Ok(_) => {}
Err(actual) => {
// This branch can only be reached if a
// concurrent thread called `wake`. In this
@@ -239,12 +225,14 @@ impl AtomicWaker {
// Take the waker to wake once the atomic operation has
// completed.
- wake_now = (*self.waker.get()).take();
+ let waker = (*self.waker.get()).take().unwrap();
- // Update `curr` for the next iteration of the
- // loop
- curr = actual;
- }
+ // Just swap, because no one could change state while state == `REGISTERING` | `WAKING`.
+ self.state.swap(WAITING, AcqRel);
+
+ // The atomic swap was complete, now
+ // wake the task and return.
+ waker.wake();
}
}
}
