use std::future::Future;
use std::task::{Context, Poll, RawWaker, RawWakerVTable, Waker};
use crate::executor;
const MAX_ROUNDS: usize = 10_000;
fn noop_raw_waker() -> RawWaker {
fn no_op(_: *const ()) {}
fn clone(_: *const ()) -> RawWaker {
noop_raw_waker()
}
static VTABLE: RawWakerVTable = RawWakerVTable::new(clone, no_op, no_op, no_op);
RawWaker::new(std::ptr::null(), &VTABLE)
}
fn noop_waker() -> Waker {
unsafe { Waker::from_raw(noop_raw_waker()) }
}
pub fn block_on<F: Future>(fut: F) -> F::Output {
let ex = executor::init();
let mut fut = Box::pin(fut);
let waker = noop_waker();
let mut cx = Context::from_waker(&waker);
for _ in 0..MAX_ROUNDS {
if let Poll::Ready(v) = fut.as_mut().poll(&mut cx) {
return v;
}
ex.run_until_idle();
}
panic!(
"block_on: the future is still pending after {MAX_ROUNDS} rounds.\n\
Either it deadlocked, or it awaited simulated time — `Timer`, a clock \
edge, `ReadOnly`/`ReadWrite`, or anything that touches a signal. Those \
need a real simulator: write the test as a `sim-*` case under \
output/regression/tests/ instead."
);
}
pub fn assert_pending<F: Future>(fut: F) {
let ex = executor::init();
let mut fut = Box::pin(fut);
let waker = noop_waker();
let mut cx = Context::from_waker(&waker);
for _ in 0..64 {
if let Poll::Ready(_) = fut.as_mut().poll(&mut cx) {
panic!("assert_pending: the future completed, but the test expected it to wait");
}
ex.run_until_idle();
}
}
pub fn fresh_executor() -> executor::Executor {
executor::init()
}