channel_bridge/
notification.rs

1use core::future::{poll_fn, Future};
2use core::sync::atomic::{AtomicBool, Ordering};
3use core::task::{Context, Poll};
4
5use atomic_waker::AtomicWaker;
6
7pub struct Notification {
8    waker: AtomicWaker,
9    triggered: AtomicBool,
10}
11
12impl Notification {
13    pub const fn new() -> Self {
14        Self {
15            waker: AtomicWaker::new(),
16            triggered: AtomicBool::new(false),
17        }
18    }
19
20    pub fn reset(&self) {
21        self.triggered.store(false, Ordering::SeqCst);
22        self.waker.take();
23    }
24
25    pub fn notify(&self) {
26        self.triggered.store(true, Ordering::SeqCst);
27        self.waker.wake();
28    }
29
30    pub fn triggered(&self) -> bool {
31        self.triggered.load(Ordering::SeqCst)
32    }
33
34    pub fn wait(&self) -> impl Future<Output = ()> + '_ {
35        poll_fn(move |cx| self.poll_wait(cx))
36    }
37
38    pub fn poll_wait(&self, cx: &mut Context<'_>) -> Poll<()> {
39        self.waker.register(cx.waker());
40
41        if self.triggered.swap(false, Ordering::SeqCst) {
42            Poll::Ready(())
43        } else {
44            Poll::Pending
45        }
46    }
47}
48
49impl Default for Notification {
50    fn default() -> Self {
51        Self::new()
52    }
53}