1use parking_lot::Mutex;
2use std::future::Future;
3use std::pin::Pin;
4use std::sync::Arc;
5use std::task::Context;
6use std::task::Poll;
7use std::task::Waker;
8
9struct State<T = ()> {
10 value: Option<T>,
11 waker: Option<Waker>,
12}
13
14#[derive(Clone)]
15pub struct SignalFutureController<T = ()> {
16 shared_state: Arc<Mutex<State<T>>>,
17}
18
19impl<T> SignalFutureController<T> {
20 pub fn signal(&self, value: T) {
21 let mut shared_state = self.shared_state.lock();
22 shared_state.value = Some(value);
23 if let Some(waker) = shared_state.waker.take() {
24 waker.wake();
25 };
26 }
27}
28
29pub struct SignalFuture<T = ()> {
53 shared_state: Arc<Mutex<State<T>>>,
54}
55
56impl<T> SignalFuture<T> {
57 pub fn new() -> (SignalFuture<T>, SignalFutureController<T>) {
58 let shared_state = Arc::new(Mutex::new(State {
59 value: None,
60 waker: None,
61 }));
62
63 (
64 SignalFuture {
65 shared_state: shared_state.clone(),
66 },
67 SignalFutureController {
68 shared_state: shared_state.clone(),
69 },
70 )
71 }
72}
73
74impl<T> Future for SignalFuture<T> {
75 type Output = T;
76
77 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
78 let mut shared_state = self.shared_state.lock();
79 if let Some(v) = shared_state.value.take() {
80 Poll::Ready(v)
81 } else {
82 shared_state.waker = Some(cx.waker().clone());
83 Poll::Pending
84 }
85 }
86}