1#![forbid(unsafe_code)]
8
9use crate::interrupt::Interrupt;
10use crate::local_only::LocalOnly;
11use crate::slim_event::SlimEvent;
12use mesh::MeshPayload;
13use pal_async::driver::Driver;
14use pal_async::wait::PolledWait;
15use pal_event::Event;
16use parking_lot::Mutex;
17use std::future::Future;
18use std::future::poll_fn;
19use std::sync::Arc;
20use std::task::Context;
21use std::task::Poll;
22
23#[derive(Debug, Clone, MeshPayload)]
25pub struct Notify(Inner);
26
27impl Notify {
28 pub fn from_event(event: Event) -> Self {
30 Self(Inner::Event(event))
31 }
32
33 pub fn from_slim_event(event: Arc<SlimEvent>) -> Self {
35 Self(Inner::SlimEvent(LocalOnly(event)))
36 }
37
38 pub fn pollable(self, driver: &(impl Driver + ?Sized)) -> std::io::Result<PolledNotify> {
41 Ok(PolledNotify(match self.0 {
42 Inner::Event(e) => PolledInner::Event(Mutex::new(PolledWait::new(driver, e)?)),
43 Inner::SlimEvent(LocalOnly(e)) => PolledInner::SlimEvent(e),
44 }))
45 }
46
47 pub fn event(&self) -> Option<&Event> {
49 match &self.0 {
50 Inner::Event(e) => Some(e),
51 Inner::SlimEvent(_) => None,
52 }
53 }
54
55 pub fn interrupt(self) -> Interrupt {
58 match self.0 {
59 Inner::Event(e) => Interrupt::from_event(e),
60 Inner::SlimEvent(LocalOnly(e)) => Interrupt::from_fn(move || e.signal()),
61 }
62 }
63}
64
65pub struct PolledNotify(PolledInner);
67
68#[derive(Debug, MeshPayload)]
69enum Inner {
70 Event(Event),
71 SlimEvent(LocalOnly<Arc<SlimEvent>>),
72}
73
74impl Clone for Inner {
75 fn clone(&self) -> Self {
76 match self {
77 Self::Event(event) => Self::Event(event.clone()),
78 Self::SlimEvent(event) => Self::SlimEvent(event.clone()),
79 }
80 }
81}
82
83enum PolledInner {
84 Event(Mutex<PolledWait<Event>>),
85 SlimEvent(Arc<SlimEvent>),
86}
87
88impl PolledNotify {
89 pub fn poll_wait(&self, cx: &mut Context<'_>) -> Poll<()> {
91 match &self.0 {
92 PolledInner::Event(e) => e
93 .lock()
94 .poll_wait(cx)
95 .map(|r| r.expect("waits on Event cannot fail")),
96 PolledInner::SlimEvent(e) => e.poll_wait(cx),
97 }
98 }
99
100 pub fn wait(&mut self) -> impl '_ + Unpin + Future<Output = ()> {
102 poll_fn(move |cx| match &mut self.0 {
103 PolledInner::Event(e) => e
104 .get_mut()
105 .poll_wait(cx)
106 .map(|r| r.expect("waits on Event cannot fail")),
107 PolledInner::SlimEvent(e) => e.poll_wait(cx),
108 })
109 }
110
111 pub fn into_inner(self) -> Notify {
113 Notify(match self.0 {
114 PolledInner::Event(e) => Inner::Event(e.into_inner().into_inner()),
115 PolledInner::SlimEvent(e) => Inner::SlimEvent(LocalOnly(e)),
116 })
117 }
118}