Skip to main content

moirai_executor/schedule/wake/
mod.rs

1//! Waker support for futures driven by scheduler workers.
2
3use std::{
4    future::Future,
5    sync::Arc,
6    task::{Context, Poll, Wake, Waker},
7    thread::{self, Thread},
8};
9
10struct ThreadWaker {
11    thread: Thread,
12}
13
14impl Wake for ThreadWaker {
15    fn wake(self: Arc<Self>) {
16        self.thread.unpark();
17    }
18
19    fn wake_by_ref(self: &Arc<Self>) {
20        self.thread.unpark();
21    }
22}
23
24/// Run a future to completion on the current thread.
25///
26/// The waker unparks the current thread, so pending futures suspend the worker
27/// without a polling sleep loop.
28pub fn block_on_current_thread<F>(future: F) -> F::Output
29where
30    F: Future,
31{
32    let waker = Waker::from(Arc::new(ThreadWaker {
33        thread: thread::current(),
34    }));
35    let mut context = Context::from_waker(&waker);
36    let mut future = std::pin::pin!(future);
37
38    loop {
39        match future.as_mut().poll(&mut context) {
40            Poll::Ready(output) => return output,
41            Poll::Pending => thread::park(),
42        }
43    }
44}
45
46#[cfg(test)]
47mod tests {
48    use super::block_on_current_thread;
49
50    #[test]
51    fn block_on_resolves_ready_future() {
52        let value = block_on_current_thread(async { 42 });
53        assert_eq!(value, 42);
54    }
55}