use super::{Reactor, REACTOR};
use core::future::Future;
use core::pin::pin;
use core::ptr;
use core::task::Waker;
use core::task::{Context, Poll, RawWaker, RawWakerVTable};
pub fn block_on<Fut>(fut: Fut) -> Fut::Output
where
Fut: Future,
{
let reactor = Reactor::new();
let prev = REACTOR.replace(Some(reactor.clone()));
if prev.is_some() {
panic!("cannot wstd::runtime::block_on inside an existing block_on!")
}
let mut fut = pin!(fut);
let waker = noop_waker();
let mut cx = Context::from_waker(&waker);
let res = loop {
match fut.as_mut().poll(&mut cx) {
Poll::Ready(res) => break res,
Poll::Pending => reactor.block_until(),
}
};
REACTOR.replace(None);
res
}
fn noop_waker() -> Waker {
const VTABLE: RawWakerVTable = RawWakerVTable::new(
|_| RAW,
|_| {},
|_| {},
|_| {},
);
const RAW: RawWaker = RawWaker::new(ptr::null(), &VTABLE);
unsafe { Waker::from_raw(RAW) }
}