diff options
| author | Dario Nieuwenhuis <[email protected]> | 2022-08-28 22:51:52 +0200 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2022-08-28 22:54:38 +0200 |
| commit | 764ee3b72cc8770f7c398ba1aee41fbd34f07764 (patch) | |
| tree | 46e48702047d98132314216fe323ec523ce68684 /embassy-futures/src | |
| parent | 973f3b513fb85b7587312196d8f3aef75be2615f (diff) | |
futures: add block_on
Diffstat (limited to 'embassy-futures/src')
| -rw-r--r-- | embassy-futures/src/block_on.rs | 31 | ||||
| -rw-r--r-- | embassy-futures/src/lib.rs | 2 |
2 files changed, 33 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 | } | ||
diff --git a/embassy-futures/src/lib.rs b/embassy-futures/src/lib.rs index 45bea2529..41e27047d 100644 --- a/embassy-futures/src/lib.rs +++ b/embassy-futures/src/lib.rs | |||
| @@ -5,8 +5,10 @@ | |||
| 5 | // This mod MUST go first, so that the others see its macros. | 5 | // This mod MUST go first, so that the others see its macros. |
| 6 | pub(crate) mod fmt; | 6 | pub(crate) mod fmt; |
| 7 | 7 | ||
| 8 | mod block_on; | ||
| 8 | mod select; | 9 | mod select; |
| 9 | mod yield_now; | 10 | mod yield_now; |
| 10 | 11 | ||
| 12 | pub use block_on::*; | ||
| 11 | pub use select::*; | 13 | pub use select::*; |
| 12 | pub use yield_now::*; | 14 | pub use yield_now::*; |
