sync/signal: wake old waker on overflow instead of panicking.

This makes behavior consistent with `WakerRegistration`. It allows canceling `wait`
in one task and then calling `wait` in another. If two tasks are `wait`ing
concurrently the signal will be received by only one of them, randomly.
This commit is contained in:
Dario Nieuwenhuis 2022-09-12 12:05:58 +02:00
parent 573c433f64
commit ea5f2c71e0

View File

@ -79,7 +79,11 @@ impl<T: Send> Signal<T> {
Poll::Pending Poll::Pending
} }
State::Waiting(w) if w.will_wake(cx.waker()) => Poll::Pending, State::Waiting(w) if w.will_wake(cx.waker()) => Poll::Pending,
State::Waiting(_) => panic!("waker overflow"), State::Waiting(w) => {
let w = mem::replace(w, cx.waker().clone());
w.wake();
Poll::Pending
}
State::Signaled(_) => match mem::replace(state, State::None) { State::Signaled(_) => match mem::replace(state, State::None) {
State::Signaled(res) => Poll::Ready(res), State::Signaled(res) => Poll::Ready(res),
_ => unreachable!(), _ => unreachable!(),