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
impl LocalExecutor
Sourcepub fn set_notify(&mut self, notify: Arc<dyn Fn() + Send + Sync>)
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.
Sourcepub fn poll_all(&mut self) -> usize
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).
Sourcepub fn is_completed(&self, id: TaskId) -> bool
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.
Sourcepub fn active_count(&self) -> usize
pub fn active_count(&self) -> usize
Number of active (non-completed) tasks.