persistant_blob/
concurrency.rs1use std::future::Future;
8use std::pin::Pin;
9use std::task::Poll;
10
11pub type Task<'a, T> = Pin<Box<dyn Future<Output = T> + 'a>>;
13
14pub async fn yield_now() {
16 let mut yielded = false;
17 std::future::poll_fn(|cx| {
18 if yielded {
19 Poll::Ready(())
20 } else {
21 yielded = true;
22 cx.waker().wake_by_ref();
23 Poll::Pending
24 }
25 })
26 .await;
27}
28
29pub async fn join_all<T>(tasks: Vec<Task<'_, T>>) -> Vec<T> {
31 let mut slots: Vec<Option<T>> = tasks.iter().map(|_| None).collect();
32 let mut tasks: Vec<Option<Task<'_, T>>> = tasks.into_iter().map(Some).collect();
33 std::future::poll_fn(|cx| {
34 let mut pending = false;
35 for (i, t) in tasks.iter_mut().enumerate() {
36 let ready = match t.as_mut() {
37 Some(fut) => match fut.as_mut().poll(cx) {
38 Poll::Ready(v) => Some(v),
39 Poll::Pending => {
40 pending = true;
41 None
42 }
43 },
44 None => None,
45 };
46 if let Some(v) = ready {
47 slots[i] = Some(v);
48 *t = None;
49 }
50 }
51 if pending {
52 Poll::Pending
53 } else {
54 Poll::Ready(())
55 }
56 })
57 .await;
58 slots.into_iter().flatten().collect()
59}