WakerRegistration: Wake previous task if any
This commit is contained in:
parent
60df9e0d38
commit
877fc0321a
@ -1,3 +1,4 @@
|
|||||||
|
use core::mem;
|
||||||
use core::task::Context;
|
use core::task::Context;
|
||||||
use core::task::Waker;
|
use core::task::Waker;
|
||||||
|
|
||||||
@ -19,11 +20,21 @@ impl WakerRegistration {
|
|||||||
// keep the old waker, skipping the clone. (In most executor implementations,
|
// keep the old waker, skipping the clone. (In most executor implementations,
|
||||||
// cloning a waker is somewhat expensive, comparable to cloning an Arc).
|
// cloning a waker is somewhat expensive, comparable to cloning an Arc).
|
||||||
Some(ref w2) if (w2.will_wake(w)) => {}
|
Some(ref w2) if (w2.will_wake(w)) => {}
|
||||||
// In all other cases
|
_ => {
|
||||||
// - we have no waker registered
|
// clone the new waker and store it
|
||||||
// - we have a waker registered but it's for a different task.
|
if let Some(old_waker) = mem::replace(&mut self.waker, Some(w.clone())) {
|
||||||
// then clone the new waker and store it
|
// We had a waker registered for another task. Wake it, so the other task can
|
||||||
_ => self.waker = Some(w.clone()),
|
// reregister itself if it's still interested.
|
||||||
|
//
|
||||||
|
// If two tasks are waiting on the same thing concurrently, this will cause them
|
||||||
|
// to wake each other in a loop fighting over this WakerRegistration. This wastes
|
||||||
|
// CPU but things will still work.
|
||||||
|
//
|
||||||
|
// If the user wants to have two tasks waiting on the same thing they should use
|
||||||
|
// a more appropriate primitive that can store multiple wakers.
|
||||||
|
old_waker.wake()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user