| 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 | /// You can use this to run multiple futures concurrently with [`join`][crate::join]. |
| 15 | /// |
| 16 | /// It's suitable for systems with no or limited concurrency and without |
| 17 | /// strict requirements around power consumption. For more complex use |
| 18 | /// cases, prefer using a "real" executor like `embassy-executor`, which |
| 19 | /// supports multiple tasks, and putting the core to sleep when no task |
| 20 | /// needs to do work. |
| 21 | pub fn block_on<F: Future>(mut fut: F) -> F::Output { |
| 22 | // safety: we don't move the future after this line. |
| 23 | let mut fut: Pin<&mut F> = unsafe { Pin::new_unchecked(&mut fut) }; |
| 24 | |
| 25 | let raw_waker: RawWaker = RawWaker::new(data:ptr::null(), &VTABLE); |
| 26 | let waker: Waker = unsafe { Waker::from_raw(raw_waker) }; |
| 27 | let mut cx: Context<'_> = Context::from_waker(&waker); |
| 28 | loop { |
| 29 | if let Poll::Ready(res: ::Output) = fut.as_mut().poll(&mut cx) { |
| 30 | return res; |
| 31 | } |
| 32 | } |
| 33 | } |
| 34 | |
| 35 | /// Poll a future once. |
| 36 | pub fn poll_once<F: Future>(mut fut: F) -> Poll<F::Output> { |
| 37 | // safety: we don't move the future after this line. |
| 38 | let mut fut: Pin<&mut F> = unsafe { Pin::new_unchecked(&mut fut) }; |
| 39 | |
| 40 | let raw_waker: RawWaker = RawWaker::new(data:ptr::null(), &VTABLE); |
| 41 | let waker: Waker = unsafe { Waker::from_raw(raw_waker) }; |
| 42 | let mut cx: Context<'_> = Context::from_waker(&waker); |
| 43 | |
| 44 | fut.as_mut().poll(&mut cx) |
| 45 | } |
| 46 | |