time: defer waker clone on spurious poll (#8107)

This commit is contained in:
Tim Vilgot Mikael Fredenberg
2026-05-02 20:39:08 -07:00
committed by GitHub
parent 50c23d300a
commit 0926ab195a
2 changed files with 9 additions and 4 deletions
+8 -3
View File
@@ -228,11 +228,16 @@ impl Handle {
} }
} }
pub(crate) fn register_waker(&self, waker: Waker) { pub(crate) fn register_waker(&self, waker: &Waker) {
let mut lock = self.entry.state.lock(); let mut lock = self.entry.state.lock();
if !lock.cancelled && !lock.woken_up { if !lock.cancelled && !lock.woken_up {
let maybe_old_waker = lock.waker.replace(waker); // PANIC: no intermediary state is possible should the user-controllable `Waker`
// unlock before calling waker // panic on `Clone` or `Drop`.
let maybe_old_waker = match &lock.waker {
Some(current_waker) if current_waker.will_wake(waker) => None,
_ => lock.waker.replace(waker.clone()),
};
// unlock before dropping waker
drop(lock); drop(lock);
drop(maybe_old_waker); drop(maybe_old_waker);
} }
+1 -1
View File
@@ -97,7 +97,7 @@ impl Timer {
match self.entry.as_ref() { match self.entry.as_ref() {
Some(entry) if entry.is_woken_up() => Poll::Ready(()), Some(entry) if entry.is_woken_up() => Poll::Ready(()),
Some(entry) => { Some(entry) => {
entry.register_waker(cx.waker().clone()); entry.register_waker(cx.waker());
Poll::Pending Poll::Pending
} }
None => self.register(cx), None => self.register(cx),