Skip to main content

LocalExecutor

Struct LocalExecutor 

Source
pub struct LocalExecutor { /* private fields */ }
Expand description

Single-threaded async executor for !Send futures.

This is the core of Kozan’s async story. It allows user code like:

let doc = ctx.document();
let btn = doc.create::<HtmlButtonElement>();

// This future is !Send — it captures `btn` (which contains Handle).
ctx.spawn(async move {
    let data = fetch("https://api.example.com").await;
    btn.set_text(&data.title);  // safe! same thread
});

§Design

Tasks are stored in a Vec with a free-list for O(1) reuse. Each task has a woken flag (Arc<AtomicBool>) — the Waker sets this atomically when the task should be polled again (safe from any thread). poll_all() only touches woken tasks — O(k) where k is woken count.

§Waker thread-safety

The Waker is backed by Arc<AtomicBool> which is Send + Sync. This means background threads (tokio runtime, rayon pool, std::thread) can safely call waker.wake() to signal that an I/O operation completed. This is the primary use case: fetch(url).await spawns HTTP work on a tokio runtime, and the completion callback calls our Waker from that background thread.

Implementations§

Source§

impl LocalExecutor

Source

pub fn new() -> Self

Create a new empty executor.

Source

pub fn set_notify(&mut self, notify: Arc<dyn Fn() + Send + Sync>)

Wire a “wake the event loop” callback into every future’s waker.

When any future’s Waker is called from a background thread, notify is invoked in addition to setting the woken flag. This lets the scheduler thread stop parking and call poll_all().

Call this once after construction, before spawning any futures.

Source

pub fn spawn(&mut self, future: impl Future<Output = ()> + 'static) -> TaskId

Spawn a !Send future on this executor.

The future will be polled on the window thread. Returns a TaskId that can be used to check completion.

ctx.spawn(async {
    let data = fetch(url).await;
    node.set_text(&data);  // !Send — safe on window thread
});
Source

pub fn poll_all(&mut self) -> usize

Poll all woken tasks. Returns the number of tasks that made progress.

Call this in the event loop after processing cross-thread wake-ups. Only polls tasks whose Waker has been invoked — idle tasks are skipped.

A task that returns Poll::Ready(()) is immediately cleaned up. A task that returns Poll::Pending stays until woken again.

§Complexity

O(s + w) where s = spawn queue length, w = woken task count. The scan over tasks checks only the atomic woken flag (branch prediction favors the not-woken path for idle tasks).

Source

pub fn is_completed(&self, id: TaskId) -> bool

Whether a specific task has completed.

Returns true for completed tasks and cleaned-up slots. Panics for out-of-range TaskIds.

Source

pub fn active_count(&self) -> usize

Number of active (non-completed) tasks.

Source

pub fn is_idle(&self) -> bool

Whether the executor has no active tasks.

Source

pub fn has_woken(&self) -> bool

Whether any task is woken and needs polling.

Trait Implementations§

Source§

impl Default for LocalExecutor

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.