freya_core/
notify.rs

1use std::{
2    cell::Cell,
3    future::Future,
4    pin::Pin,
5    rc::Rc,
6    task::{
7        Context,
8        Poll,
9        Waker,
10    },
11};
12
13#[derive(Clone, Default)]
14pub struct Notify {
15    state: Rc<State>,
16}
17
18#[derive(Default)]
19struct State {
20    flag: Cell<bool>,
21    waker: Cell<Option<Waker>>,
22}
23
24impl Notify {
25    pub fn new() -> Self {
26        Self {
27            state: Rc::new(State {
28                flag: Cell::new(false),
29                waker: Cell::new(None),
30            }),
31        }
32    }
33
34    pub fn notify(&self) {
35        self.state.flag.set(true);
36
37        if let Some(w) = self.state.waker.take() {
38            w.wake();
39        }
40    }
41
42    pub fn notified(&self) -> Notified {
43        Notified {
44            state: self.state.clone(),
45        }
46    }
47}
48
49pub struct Notified {
50    state: Rc<State>,
51}
52
53impl Future for Notified {
54    type Output = ();
55
56    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> {
57        if self.state.flag.replace(false) {
58            Poll::Ready(())
59        } else {
60            self.state.waker.set(Some(cx.waker().clone()));
61            Poll::Pending
62        }
63    }
64}