1#![cfg_attr(docsrs, feature(doc_cfg))]
4#![warn(missing_docs)]
5
6use std::{
7 cell::RefCell,
8 future::Future,
9 hint::unreachable_unchecked,
10 pin::Pin,
11 sync::Mutex,
12 task::{Context, Poll, Waker},
13};
14
15pub trait Runnable {
17 fn run();
20}
21
22impl Runnable for () {
23 fn run() {}
24}
25
26#[derive(Debug)]
27enum WakerState<T> {
28 Inactive,
29 Active(Waker),
30 Signaled(T),
31}
32
33#[derive(Debug)]
35pub struct Callback<T = ()>(RefCell<WakerState<T>>);
36
37impl<T> Default for Callback<T> {
38 fn default() -> Self {
39 Self::new()
40 }
41}
42
43impl<T> Callback<T> {
44 pub fn new() -> Self {
46 Self(RefCell::new(WakerState::Inactive))
47 }
48
49 pub fn signal<R: Runnable>(&self, v: T) -> bool {
52 let mut state = self.0.borrow_mut();
53 match &*state {
54 WakerState::Inactive => return true,
55 WakerState::Signaled(_) => {
56 }
59 WakerState::Active(waker) => {
60 waker.wake_by_ref();
61 }
62 }
63 *state = WakerState::Signaled(v);
64 drop(state);
65 R::run();
66 false
67 }
68
69 pub(crate) fn register(&self, waker: &Waker) -> Poll<T> {
70 let mut state = self.0.borrow_mut();
71 match &*state {
72 WakerState::Signaled(_) => {
73 let state = std::mem::replace(&mut *state, WakerState::Inactive);
74 let v = if let WakerState::Signaled(v) = state {
75 v
76 } else {
77 unsafe { unreachable_unchecked() }
79 };
80 Poll::Ready(v)
81 }
82 _ => {
83 *state = WakerState::Active(waker.clone());
84 Poll::Pending
85 }
86 }
87 }
88
89 pub fn wait(&self) -> impl Future<Output = T> + '_ {
91 WaitFut(self)
92 }
93}
94
95struct WaitFut<'a, T>(&'a Callback<T>);
96
97impl<T> Future for WaitFut<'_, T> {
98 type Output = T;
99
100 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
101 self.0.register(cx.waker())
102 }
103}
104
105impl<T> Drop for WaitFut<'_, T> {
106 fn drop(&mut self) {
107 *self.0.0.borrow_mut() = WakerState::Inactive;
109 }
110}
111
112#[derive(Debug)]
114pub struct SyncCallback<T = ()>(Mutex<WakerState<T>>);
115
116impl<T> Default for SyncCallback<T> {
117 fn default() -> Self {
118 Self::new()
119 }
120}
121
122impl<T> SyncCallback<T> {
123 pub fn new() -> Self {
125 Self(Mutex::new(WakerState::Inactive))
126 }
127
128 pub fn signal(&self, v: T) -> bool {
131 let mut state = self.0.lock().unwrap();
132 match &*state {
133 WakerState::Inactive => return true,
134 WakerState::Signaled(_) => {
135 }
138 WakerState::Active(waker) => {
139 waker.wake_by_ref();
140 }
141 }
142 *state = WakerState::Signaled(v);
143 false
144 }
145
146 pub(crate) fn register(&self, waker: &Waker) -> Poll<T> {
147 let mut state = self.0.lock().unwrap();
148 match &*state {
149 WakerState::Signaled(_) => {
150 let state = std::mem::replace(&mut *state, WakerState::Inactive);
151 let v = if let WakerState::Signaled(v) = state {
152 v
153 } else {
154 unsafe { unreachable_unchecked() }
156 };
157 Poll::Ready(v)
158 }
159 _ => {
160 *state = WakerState::Active(waker.clone());
161 Poll::Pending
162 }
163 }
164 }
165
166 pub fn wait(&self) -> impl Future<Output = T> + '_ {
168 SyncWaitFut(self)
169 }
170}
171
172struct SyncWaitFut<'a, T>(&'a SyncCallback<T>);
173
174impl<T> Future for SyncWaitFut<'_, T> {
175 type Output = T;
176
177 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
178 self.0.register(cx.waker())
179 }
180}
181
182impl<T> Drop for SyncWaitFut<'_, T> {
183 fn drop(&mut self) {
184 *self.0.0.lock().unwrap() = WakerState::Inactive;
186 }
187}