#![doc = include_str!("../README.md")]
#![cfg_attr(docsrs, feature(doc_cfg))]
use std::{
future::{Future, IntoFuture},
sync::Arc,
task::{Context, Poll, Wake, Waker},
thread,
};
thread_local! {
static LOCAL_WAKER: Waker = {
let signal = Arc::new(Signal {
owning_thread: thread::current(),
});
Waker::from(signal)
};
}
#[cfg(feature = "macro")]
pub use pollster_macro::{main, test};
pub trait FutureExt: IntoFuture {
fn block_on(self) -> Self::Output
where
Self: Sized,
{
block_on(self)
}
}
impl<F: IntoFuture> FutureExt for F {}
struct Signal {
owning_thread: thread::Thread,
}
impl Wake for Signal {
fn wake(self: Arc<Self>) {
self.owning_thread.unpark();
}
fn wake_by_ref(self: &Arc<Self>) {
self.owning_thread.unpark();
}
}
pub fn block_on<F: IntoFuture>(fut: F) -> F::Output {
let mut fut = core::pin::pin!(fut.into_future());
LOCAL_WAKER.with(|waker| {
let mut context = Context::from_waker(waker);
loop {
match fut.as_mut().poll(&mut context) {
Poll::Pending => thread::park(),
Poll::Ready(item) => break item,
}
}
})
}