1#![no_std]
5#![deny(
6 missing_docs,
7 missing_debug_implementations,
8 missing_copy_implementations,
9 trivial_casts,
10 trivial_numeric_casts,
11 unstable_features,
12 unused_import_braces,
13 unused_qualifications,
14 clippy::all
15)]
16
17use core::future;
18use core::task;
19
20pub fn run_spinning<F>(future: F) -> F::Output
24where
25 F: future::Future,
26{
27 run(future, || core::sync::atomic::spin_loop_hint())
28}
29
30pub fn run<F>(future: F, wait: impl FnMut()) -> F::Output
37where
38 F: future::Future,
39{
40 run_with_wake(future, wait, || {})
41}
42
43pub fn run_with_wake<F>(future: F, mut wait: impl FnMut(), wake: fn()) -> F::Output
53where
54 F: future::Future,
55{
56 pin_utils::pin_mut!(future);
57
58 let raw_waker = raw_waker(&wake);
59 let waker = unsafe { task::Waker::from_raw(raw_waker) };
60 let mut context = task::Context::from_waker(&waker);
61
62 loop {
63 if let task::Poll::Ready(result) = future.as_mut().poll(&mut context) {
64 return result;
65 }
66 wait();
67 }
68}
69
70static VTABLE: task::RawWakerVTable = task::RawWakerVTable::new(clone, wake, wake, drop);
71
72fn raw_waker(wake_ptr: *const fn()) -> task::RawWaker {
73 task::RawWaker::new(wake_ptr as *const (), &VTABLE)
74}
75
76fn clone(wake_ptr: *const ()) -> task::RawWaker {
77 raw_waker(wake_ptr as *const fn())
78}
79
80fn wake(wake_ptr: *const ()) {
81 let wake = unsafe { (wake_ptr as *const fn()).as_ref() }.unwrap();
82 wake();
83}
84
85fn drop(_wake_ptr: *const ()) {}