1use std::{
5 future::Future,
6 pin::Pin,
7 sync::Arc,
8 task::{
9 Context,
10 Poll,
11 },
12};
13
14type NotifiedBox<'a> = Pin<Box<dyn Future<Output = ()> + Send + 'a>>;
15
16pub struct Notify {
17 notify: Arc<tokio::sync::Notify>,
18}
19
20impl Notify {
21 pub fn new() -> Self {
22 Self {
23 notify: Arc::new(tokio::sync::Notify::new()),
24 }
25 }
26
27 pub fn notified(&self) -> Notified {
28 Notified {
29 notify: self.notify.clone(),
30 notified: None,
31 }
32 }
33
34 pub fn notify_waiters(&self) {
35 self.notify.notify_waiters();
36 }
37}
38
39pub struct Notified {
40 notify: Arc<tokio::sync::Notify>,
41 notified: Option<NotifiedBox<'static>>,
42}
43
44impl Drop for Notified {
45 fn drop(&mut self) {
46 drop(self.notified.take());
48 }
49}
50
51impl Clone for Notified {
52 fn clone(&self) -> Self {
53 Self {
54 notify: self.notify.clone(),
55 notified: None,
56 }
57 }
58}
59
60impl Future for Notified {
61 type Output = ();
62
63 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
64 let this = self.get_mut();
65 if this.notified.is_none() {
66 let notified: NotifiedBox<'_> = Box::pin(this.notify.notified());
67 let notified =
70 unsafe { std::mem::transmute::<NotifiedBox<'_>, NotifiedBox<'static>>(notified) };
71 this.notified = Some(notified);
72 }
73 this.notified.as_mut().unwrap().as_mut().poll(cx)
74 }
75}