use std::{ future::Future, sync::Arc, task::{Context, Poll, Wake}, }; struct ThreadWaker { thread: std::thread::Thread, } impl Wake for ThreadWaker { fn wake(self: Arc) { self.thread.unpark(); } fn wake_by_ref(self: &Arc) { self.thread.unpark(); } } pub(super) fn block_on(fut: F) -> F::Output where F: Future, { let thread_waker = Arc::new(ThreadWaker { thread: std::thread::current(), }) .into(); let mut ctx = Context::from_waker(&thread_waker); let mut fut = std::pin::pin!(fut); loop { if let Poll::Ready(out) = fut.as_mut().poll(&mut ctx) { return out; } // doesn't race - unpark followed by park will result in park returning immediately std::thread::park(); } }