1#![doc = include_str!("../README.md")]
2#![cfg_attr(docsrs, feature(doc_cfg))]
3
4use std::{
5 future::{Future, IntoFuture},
6 sync::Arc,
7 task::{Context, Poll, Wake, Waker},
8 thread,
9};
10
11thread_local! {
12 static LOCAL_WAKER: Waker = {
14 let signal = Arc::new(Signal {
15 owning_thread: thread::current(),
16 });
17 Waker::from(signal)
18 };
19}
20
21#[cfg(feature = "macro")]
22pub use pollster_macro::{main, test};
23
24pub trait FutureExt: IntoFuture {
26 fn block_on(self) -> Self::Output
38 where
39 Self: Sized,
40 {
41 block_on(self)
42 }
43}
44
45impl<F: IntoFuture> FutureExt for F {}
46
47struct Signal {
48 owning_thread: thread::Thread,
50}
51
52impl Wake for Signal {
53 fn wake(self: Arc<Self>) {
54 self.owning_thread.unpark();
55 }
56
57 fn wake_by_ref(self: &Arc<Self>) {
58 self.owning_thread.unpark();
59 }
60}
61
62pub fn block_on<F: IntoFuture>(fut: F) -> F::Output {
71 let mut fut = core::pin::pin!(fut.into_future());
72
73 LOCAL_WAKER.with(|waker| {
75 let mut context = Context::from_waker(waker);
77
78 loop {
80 match fut.as_mut().poll(&mut context) {
81 Poll::Pending => thread::park(),
82 Poll::Ready(item) => break item,
83 }
84 }
85 })
86}