Diffstat (limited to 'src/effect/blocking/spin.rs')
-rw-r--r--src/effect/blocking/spin.rs46
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) }
+}