embassy_sync/waitqueue/
atomic_waker.rs1use core::cell::Cell;
2use core::task::Waker;
3
4use crate::blocking_mutex::raw::{CriticalSectionRawMutex, RawMutex};
5use crate::blocking_mutex::Mutex;
6
7pub struct GenericAtomicWaker<M: RawMutex> {
12 waker: Mutex<M, Cell<Option<Waker>>>,
13}
14
15impl<M: RawMutex> GenericAtomicWaker<M> {
16 pub const fn new(mutex: M) -> Self {
18 Self {
19 waker: Mutex::const_new(mutex, Cell::new(None)),
20 }
21 }
22
23 pub fn register(&self, w: &Waker) {
25 self.waker.lock(|cell| {
26 cell.set(match cell.replace(None) {
27 Some(w2) if (w2.will_wake(w)) => Some(w2),
28 _ => Some(w.clone()),
29 })
30 })
31 }
32
33 pub fn wake(&self) {
35 self.waker.lock(|cell| {
36 if let Some(w) = cell.replace(None) {
37 w.wake_by_ref();
38 cell.set(Some(w));
39 }
40 })
41 }
42}
43
44pub struct AtomicWaker {
46 waker: GenericAtomicWaker<CriticalSectionRawMutex>,
47}
48
49impl AtomicWaker {
50 pub const fn new() -> Self {
52 Self {
53 waker: GenericAtomicWaker::new(CriticalSectionRawMutex::new()),
54 }
55 }
56
57 pub fn register(&self, w: &Waker) {
59 self.waker.register(w);
60 }
61
62 pub fn wake(&self) {
64 self.waker.wake();
65 }
66}