aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2021-01-11 10:38:25 +0100
committerDario Nieuwenhuis <[email protected]>2021-01-11 10:38:25 +0100
commit877fc0321a0a6a56f38bdbe3ce03b77b44ab8316 (patch)
treeeffea24198d86714b3f99af7fc1d009f17aafb54
parent60df9e0d38994509a595710a52d71baab1d7c28c (diff)
WakerRegistration: Wake previous task if any
-rw-r--r--embassy/src/util/waker.rs23
1 files changed, 17 insertions, 6 deletions
diff --git a/embassy/src/util/waker.rs b/embassy/src/util/waker.rs
index 9735438b5..83fd8b4ff 100644
--- a/embassy/src/util/waker.rs
+++ b/embassy/src/util/waker.rs
@@ -1,3 +1,4 @@
1use core::mem;
1use core::task::Context; 2use core::task::Context;
2use core::task::Waker; 3use core::task::Waker;
3 4
@@ -19,11 +20,21 @@ impl WakerRegistration {
19 // keep the old waker, skipping the clone. (In most executor implementations, 20 // keep the old waker, skipping the clone. (In most executor implementations,
20 // cloning a waker is somewhat expensive, comparable to cloning an Arc). 21 // cloning a waker is somewhat expensive, comparable to cloning an Arc).
21 Some(ref w2) if (w2.will_wake(w)) => {} 22 Some(ref w2) if (w2.will_wake(w)) => {}
22 // In all other cases 23 _ => {
23 // - we have no waker registered 24 // clone the new waker and store it
24 // - we have a waker registered but it's for a different task. 25 if let Some(old_waker) = mem::replace(&mut self.waker, Some(w.clone())) {
25 // then clone the new waker and store it 26 // We had a waker registered for another task. Wake it, so the other task can
26 _ => self.waker = Some(w.clone()), 27 // reregister itself if it's still interested.
28 //
29 // If two tasks are waiting on the same thing concurrently, this will cause them
30 // to wake each other in a loop fighting over this WakerRegistration. This wastes
31 // CPU but things will still work.
32 //
33 // If the user wants to have two tasks waiting on the same thing they should use
34 // a more appropriate primitive that can store multiple wakers.
35 old_waker.wake()
36 }
37 }
27 } 38 }
28 } 39 }
29 40
@@ -35,4 +46,4 @@ impl WakerRegistration {
35 pub fn context(&self) -> Option<Context<'_>> { 46 pub fn context(&self) -> Option<Context<'_>> {
36 self.waker.as_ref().map(|w| Context::from_waker(w)) 47 self.waker.as_ref().map(|w| Context::from_waker(w))
37 } 48 }
38} \ No newline at end of file 49}