1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
//! An asynchronous executor.
//!
//! This crate is very experimental. We currently spawn an OS thread (task) per
//! future, and use run states to wake the executor. Calling it an executor is
//! generous. It's merely a wrapper around a future that communicates between
//! the waker and the task system.
//!
//! The executor polls the future, passing in a waker which will unblock the
//! current task when awoken. If the future returns pending, the executor will
//! block the current task. When the future uses the waker, it unblocks the
//! task, and the executor loops around, polling the future again. It will
//! continue doing so until the future returns ready.
//!
//! The crate is named after the [Executor-class Start
//! Dreadnought][dreadnought] (`super_star_destroyer` was a bit too on the
//! nose).
//!
//! [dreadnought]: https://starwars.fandom.com/wiki/Executor-class_Star_Dreadnought
#![no_std]
extern crate alloc;
use core::{
future::Future,
task::{Context, Poll},
};
pub use futures::{future, pin_mut, select_biased, FutureExt};
pub mod task;
pub mod time;
/// Executes a future to completion.
///
/// This runs the given future on the current thread, blocking until it is
/// complete, and yielding its result.
pub fn block_on<F>(future: F) -> F::Output
where
F: Future,
{
// Pin the future onto the stack. This works because we don't send it anywhere.
pin_mut!(future);
let (waker, blocker) = waker::new_waker();
let mut context = Context::from_waker(&waker);
loop {
match future.as_mut().poll(&mut context) {
Poll::Ready(output) => return output,
Poll::Pending => blocker.block(),
}
}
}