use core::{ pin::pin, ptr, task::{Context, Poll, RawWaker, RawWakerVTable, Waker}, }; use super::BlockOn; /// [`BlockOn`] implementer that just spins on the future. /// /// This is useful for futures that are alwayd ready. pub enum Spin {} impl BlockOn for Spin { #[inline(always)] fn block_on(future: F) -> F::Output where F: core::future::Future + Send, { let waker = noop(); let mut context = Context::from_waker(&waker); let mut future = pin!(future); loop { if let Poll::Ready(value) = future.as_mut().poll(&mut context) { return value; } } } } #[inline] pub fn noop() -> Waker { const VTABLE: &RawWakerVTable = &RawWakerVTable::new( // Cloning just returns a new no-op raw waker |_| RAW, // `wake` does nothing |_| {}, // `wake_by_ref` does nothing |_| {}, // Dropping does nothing as we don't allocate anything |_| {}, ); const RAW: RawWaker = RawWaker::new(ptr::null(), VTABLE); unsafe { Waker::from_raw(RAW) } }