1use anyhow::Result;
3use pin_project::pin_project;
4use std::{
5 future::Future,
6 num::NonZeroU32,
7 ops::ControlFlow,
8 pin::Pin,
9 sync::{Condvar, Mutex},
10 task::{Context, Poll},
11};
12use tokio::sync::{mpsc::UnboundedReceiver, oneshot};
13
14pub async fn channel_reader<MessageT>(
17 mut channel: UnboundedReceiver<MessageT>,
18 mut processor: impl FnMut(MessageT) -> ControlFlow<Result<()>>,
19) -> Result<()> {
20 while let Some(x) = channel.recv().await {
21 if let ControlFlow::Break(result) = processor(x) {
22 return result;
23 }
24 }
25 Ok(())
26}
27
28enum Never {}
30
31pub struct EventSender {
34 _sender: oneshot::Sender<Never>,
35}
36
37#[pin_project]
39pub struct EventReceiver(#[pin] oneshot::Receiver<Never>);
40
41impl Future for EventReceiver {
42 type Output = ();
43
44 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
45 self.project().0.poll(cx).map(drop)
46 }
47}
48
49pub fn event() -> (EventSender, EventReceiver) {
51 let (_sender, receiver) = oneshot::channel();
52 (EventSender { _sender }, EventReceiver(receiver))
53}
54
55#[derive(Default)]
56pub struct Event {
57 completed: std::sync::Mutex<bool>,
58 condvar: std::sync::Condvar,
59}
60
61impl Event {
62 pub fn new() -> Self {
63 Self::default()
64 }
65
66 pub fn set(&self) {
67 *self.completed.lock().unwrap() = true;
68 self.condvar.notify_all();
69 }
70
71 pub fn wait(&self) {
72 let _guard = self
73 .condvar
74 .wait_while(self.completed.lock().unwrap(), |completed| !*completed)
75 .unwrap();
76 }
77
78 pub fn wait_and_unset(&self) {
79 let _guard = self
80 .condvar
81 .wait_while(self.completed.lock().unwrap(), |completed| {
82 if *completed {
83 *completed = false;
84 false
85 } else {
86 true
87 }
88 })
89 .unwrap();
90 }
91
92 pub fn wait_timeout(&self, dur: std::time::Duration) -> std::sync::WaitTimeoutResult {
93 let (_guard, result) = self
94 .condvar
95 .wait_timeout_while(self.completed.lock().unwrap(), dur, |completed| !*completed)
96 .unwrap();
97 result
98 }
99
100 pub fn is_set(&self) -> bool {
101 *self.completed.lock().unwrap()
102 }
103}
104
105pub struct Pool<T> {
106 mutex: Mutex<PoolInner<T>>,
107 condvar: Condvar,
108}
109
110struct PoolInner<T> {
111 available_slots: u32,
112 available_items: Vec<T>,
113}
114
115impl<T> Pool<T> {
116 pub fn new(slots: NonZeroU32) -> Self {
117 Self {
118 mutex: Mutex::new(PoolInner {
119 available_slots: slots.into(),
120 available_items: Default::default(),
121 }),
122 condvar: Default::default(),
123 }
124 }
125
126 pub fn call_with_item<U, E>(
133 &self,
134 f: impl FnOnce(Option<T>) -> Result<(T, U), E>,
135 ) -> Result<U, E> {
136 let guard = self.mutex.lock().unwrap();
137 let mut guard = self
138 .condvar
139 .wait_while(guard, |inner| inner.available_slots == 0)
140 .unwrap();
141 guard.available_slots -= 1;
142 let item = guard.available_items.pop();
143 drop(guard);
144
145 let result = f(item);
146
147 let mut guard = self.mutex.lock().unwrap();
148 guard.available_slots += 1;
149 let result = result.map(|(item, ret)| {
150 guard.available_items.push(item);
151 ret
152 });
153 drop(guard);
154
155 self.condvar.notify_one();
156 result
157 }
158}
159
160#[cfg(test)]
161mod tests {
162 use super::*;
163 use anyhow::anyhow;
164 use core::time::Duration;
165 use tokio::{sync::mpsc, task, time};
166
167 #[tokio::test]
168 async fn no_messages() {
169 let (_, rx) = mpsc::unbounded_channel::<u8>();
170 let mut vec = vec![];
171 channel_reader(rx, |s| {
172 vec.push(s);
173 ControlFlow::Continue(())
174 })
175 .await
176 .unwrap();
177 assert!(vec.is_empty(), "{vec:?}");
178 }
179
180 #[tokio::test]
181 async fn one_messages() {
182 let (tx, rx) = mpsc::unbounded_channel();
183 task::spawn(async move { tx.send(1).unwrap() });
184 let mut vec = vec![];
185 channel_reader(rx, |s| {
186 vec.push(s);
187 ControlFlow::Continue(())
188 })
189 .await
190 .unwrap();
191
192 assert_eq!(vec, vec![1]);
193 }
194
195 #[tokio::test]
196 async fn three_messages() {
197 let (tx, rx) = mpsc::unbounded_channel();
198 task::spawn(async move {
199 tx.send(1).unwrap();
200 tx.send(2).unwrap();
201 tx.send(3).unwrap();
202 });
203 let mut vec = vec![];
204 channel_reader(rx, |s| {
205 vec.push(s);
206 ControlFlow::Continue(())
207 })
208 .await
209 .unwrap();
210
211 assert_eq!(vec, vec![1, 2, 3]);
212 }
213
214 #[tokio::test]
215 async fn three_messages_with_break_after_two() {
216 let (tx, rx) = mpsc::unbounded_channel();
217 task::spawn(async move {
218 tx.send(1).unwrap();
219 tx.send(2).unwrap();
220 tx.send(3).unwrap();
221 });
222 let mut vec = vec![];
223 channel_reader(rx, |s| {
224 vec.push(s);
225 if s == 2 {
226 ControlFlow::Break(Ok(()))
227 } else {
228 ControlFlow::Continue(())
229 }
230 })
231 .await
232 .unwrap();
233
234 assert_eq!(vec, vec![1, 2]);
235 }
236
237 #[tokio::test]
238 async fn three_messages_with_break_of_error_after_two() {
239 let (tx, rx) = mpsc::unbounded_channel();
240 task::spawn(async move {
241 tx.send(1).unwrap();
242 tx.send(2).unwrap();
243 tx.send(3).unwrap();
244 });
245 let mut vec = vec![];
246 let err = channel_reader(rx, |s| {
247 vec.push(s);
248 if s == 2 {
249 ControlFlow::Break(Err(anyhow!("test error")))
250 } else {
251 ControlFlow::Continue(())
252 }
253 })
254 .await
255 .unwrap_err();
256 assert_eq!(err.to_string(), "test error");
257
258 assert_eq!(vec, vec![1, 2]);
259 }
260
261 #[tokio::test]
262 async fn basic_event() {
263 let (event_sender, event_receiver) = event();
264 task::spawn(async move {
265 drop(event_sender);
266 });
267 event_receiver.await;
268 }
269
270 #[tokio::test]
271 async fn event_sent_before_received() {
272 let (event_sender, event_receiver) = event();
273 let (channel_sender, channel_receiver) = oneshot::channel();
274 task::spawn(async move {
275 drop(event_sender);
276 channel_sender.send(()).unwrap();
277 });
278 channel_receiver.await.unwrap();
279 event_receiver.await;
280 }
281
282 #[tokio::test]
283 async fn event_sent_after_received() {
284 let (event_sender, event_receiver) = event();
285 let (channel_sender, channel_receiver) = oneshot::channel();
286 task::spawn(async move {
287 channel_receiver.await.unwrap();
288 drop(event_sender);
289 });
290 channel_sender.send(()).unwrap();
291 time::sleep(Duration::from_millis(10)).await;
292 event_receiver.await;
293 }
294
295 #[tokio::test]
296 async fn event_sent_after_receiver_dropped() {
297 let (event_sender, event_receiver) = event();
298 let (channel_sender, channel_receiver) = oneshot::channel();
299 let handle = task::spawn(async move {
300 channel_receiver.await.unwrap();
301 drop(event_sender);
302 });
303 drop(event_receiver);
304 channel_sender.send(()).unwrap();
305 handle.await.unwrap();
306 }
307
308 #[test]
309 fn sync_event_wait() {
310 let event = Event::new();
311
312 std::thread::scope(|scope| {
313 let t1 = scope.spawn(|| event.wait());
314 let t2 = scope.spawn(|| event.wait());
315
316 std::thread::sleep(Duration::from_millis(10));
317 assert!(!t1.is_finished());
318 assert!(!t2.is_finished());
319
320 assert!(!event.is_set());
321 event.set();
322
323 t1.join().unwrap();
324 t2.join().unwrap();
325 assert!(event.is_set());
326 });
327 }
328
329 #[test]
330 fn sync_event_wait_timeout() {
331 let event = Event::new();
332
333 assert!(event.wait_timeout(Duration::from_millis(5)).timed_out());
334 event.set();
335 assert!(!event.wait_timeout(Duration::from_millis(5)).timed_out());
336 }
337
338 #[test]
339 fn sync_event_wait_and_unset() {
340 let event = Event::new();
341
342 std::thread::scope(|scope| {
343 let t1 = scope.spawn(|| event.wait_and_unset());
344 let t2 = scope.spawn(|| event.wait_and_unset());
345
346 event.set();
347 while !t1.is_finished() && !t2.is_finished() {
348 std::thread::sleep(Duration::from_millis(1));
349 }
350 assert!(!event.is_set());
351
352 event.set();
353 t1.join().unwrap();
354 t2.join().unwrap();
355
356 assert!(!event.is_set());
357 });
358 }
359}