43 lines
825 B
Rust
43 lines
825 B
Rust
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>) {
|
|
self.thread.unpark();
|
|
}
|
|
|
|
fn wake_by_ref(self: &Arc<Self>) {
|
|
self.thread.unpark();
|
|
}
|
|
}
|
|
|
|
pub(super) fn block_on<F>(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();
|
|
}
|
|
}
|