mirror of
https://github.com/embassy-rs/embassy.git
synced 2024-10-30 05:40:55 +00:00
futures: add block_on
This commit is contained in:
parent
973f3b513f
commit
764ee3b72c
31
embassy-futures/src/block_on.rs
Normal file
31
embassy-futures/src/block_on.rs
Normal file
@ -0,0 +1,31 @@
|
||||
use core::future::Future;
|
||||
use core::pin::Pin;
|
||||
use core::ptr;
|
||||
use core::task::{Context, Poll, RawWaker, RawWakerVTable, Waker};
|
||||
|
||||
static VTABLE: RawWakerVTable = RawWakerVTable::new(|_| RawWaker::new(ptr::null(), &VTABLE), |_| {}, |_| {}, |_| {});
|
||||
|
||||
/// Run a future to completion using a busy loop.
|
||||
///
|
||||
/// This calls `.poll()` on the future in a busy loop, which blocks
|
||||
/// the current thread at 100% cpu usage until the future is done. The
|
||||
/// future's `Waker` mechanism is not used.
|
||||
///
|
||||
/// It's suitable for systems with no or limited concurrency and without
|
||||
/// strict requirements around power consumption. For more complex use
|
||||
/// cases, prefer using a "real" executor like `embassy-executor`, which
|
||||
/// supports multiple tasks, and putting the core to sleep when no task
|
||||
/// needs to do work.
|
||||
pub fn block_on<F: Future>(mut fut: F) -> F::Output {
|
||||
// safety: we don't move the future after this line.
|
||||
let mut fut = unsafe { Pin::new_unchecked(&mut fut) };
|
||||
|
||||
let raw_waker = RawWaker::new(ptr::null(), &VTABLE);
|
||||
let waker = unsafe { Waker::from_raw(raw_waker) };
|
||||
let mut cx = Context::from_waker(&waker);
|
||||
loop {
|
||||
if let Poll::Ready(res) = fut.as_mut().poll(&mut cx) {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
@ -5,8 +5,10 @@
|
||||
// This mod MUST go first, so that the others see its macros.
|
||||
pub(crate) mod fmt;
|
||||
|
||||
mod block_on;
|
||||
mod select;
|
||||
mod yield_now;
|
||||
|
||||
pub use block_on::*;
|
||||
pub use select::*;
|
||||
pub use yield_now::*;
|
||||
|
Loading…
Reference in New Issue
Block a user