local_ex/
lib.rs

1use std::{
2    future::Future,
3    task::{Context, Poll},
4};
5
6use async_executor::{LocalExecutor, Task};
7
8pub struct LocalEx;
9impl LocalEx {
10    thread_local!(static EX: LocalExecutor<'static> = LocalExecutor::new());
11    pub fn spawn<T: 'static>(fut: impl Future<Output = T> + 'static) -> Task<T> {
12        Self::EX.with(|e| e.spawn(fut))
13    }
14
15    pub fn run<F: Future>(task: F) -> F::Output {
16        Self::EX.with(|ex| {
17            futures_lite::pin!(task);
18
19            let this = std::thread::current();
20            let waker = waker_fn::waker_fn(move || {
21                this.unpark();
22            });
23            let mut cx = Context::from_waker(&waker);
24
25            loop {
26                if let Poll::Ready(r) = task.as_mut().poll(&mut cx) {
27                    return r;
28                }
29                while ex.try_tick() {}
30
31                let fut = ex.tick();
32                futures_lite::pin!(fut);
33
34                match fut.poll(&mut cx) {
35                    Poll::Ready(_) => (),
36                    Poll::Pending => std::thread::park(),
37                }
38            }
39        })
40    }
41}