diff options
Diffstat (limited to 'embassy-futures/src/block_on.rs')
| -rw-r--r-- | embassy-futures/src/block_on.rs | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/embassy-futures/src/block_on.rs b/embassy-futures/src/block_on.rs new file mode 100644 index 000000000..749fa67f3 --- /dev/null +++ b/embassy-futures/src/block_on.rs | |||
| @@ -0,0 +1,31 @@ | |||
| 1 | use core::future::Future; | ||
| 2 | use core::pin::Pin; | ||
| 3 | use core::ptr; | ||
| 4 | use core::task::{Context, Poll, RawWaker, RawWakerVTable, Waker}; | ||
| 5 | |||
| 6 | static VTABLE: RawWakerVTable = RawWakerVTable::new(|_| RawWaker::new(ptr::null(), &VTABLE), |_| {}, |_| {}, |_| {}); | ||
| 7 | |||
| 8 | /// Run a future to completion using a busy loop. | ||
| 9 | /// | ||
| 10 | /// This calls `.poll()` on the future in a busy loop, which blocks | ||
| 11 | /// the current thread at 100% cpu usage until the future is done. The | ||
| 12 | /// future's `Waker` mechanism is not used. | ||
| 13 | /// | ||
| 14 | /// It's suitable for systems with no or limited concurrency and without | ||
| 15 | /// strict requirements around power consumption. For more complex use | ||
| 16 | /// cases, prefer using a "real" executor like `embassy-executor`, which | ||
| 17 | /// supports multiple tasks, and putting the core to sleep when no task | ||
| 18 | /// needs to do work. | ||
| 19 | pub fn block_on<F: Future>(mut fut: F) -> F::Output { | ||
| 20 | // safety: we don't move the future after this line. | ||
| 21 | let mut fut = unsafe { Pin::new_unchecked(&mut fut) }; | ||
| 22 | |||
| 23 | let raw_waker = RawWaker::new(ptr::null(), &VTABLE); | ||
| 24 | let waker = unsafe { Waker::from_raw(raw_waker) }; | ||
| 25 | let mut cx = Context::from_waker(&waker); | ||
| 26 | loop { | ||
| 27 | if let Poll::Ready(res) = fut.as_mut().poll(&mut cx) { | ||
| 28 | return res; | ||
| 29 | } | ||
| 30 | } | ||
| 31 | } | ||
