Diffstat (limited to 'src/effect/blocking/spin.rs')
| -rw-r--r-- | src/effect/blocking/spin.rs | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/src/effect/blocking/spin.rs b/src/effect/blocking/spin.rs new file mode 100644 index 0000000..2193a3d --- /dev/null +++ b/src/effect/blocking/spin.rs @@ -0,0 +1,46 @@ +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<F>(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) } +} |