pub struct SpawnerSlot { /* private fields */ }Expand description
Runtime-filled slot holding a foreign executor’s SendSpawner.
Declared by executor NAME; and filled by the app before or during
Supervisor::start. The supervisor waits on ready
before spawning a node into it; if the slot is still empty after the
bounded wait, the spawn fails with FaultKind::ExecutorSlotEmpty.
default executor NAME; makes NAME the default for nodes that do not
specify an executor. This lets a supervisor running on an interrupt tier
keep most of its graph in thread mode:
supervisor_graph! {
default executor THREAD;
executor HIGH;
node LOGGER = Terminate, task: logger_worker;
node SAMPLER = Terminate, executor: HIGH, task: sampler_worker;
}
THREAD.set(spawner.make_send());Send is required on the spawn arguments, not the future. A task: shell’s
arguments are always Send, so any task: worker can be routed to any tier.
A spawn: fn’s own arguments must be Send, so this does not compile:
use std::rc::Rc;
use embassy_supervisor::{TaskNode, supervisor_graph};
#[embassy_executor::task]
async fn worker(_node: &'static TaskNode, _handle: Rc<u32>) {}
supervisor_graph! {
executor HIGH;
node A = Terminate, deps: [], executor: HIGH, spawn: worker(Rc::new(1));
}What the worker then touches from that tier is the author’s contract.
Implementations§
Source§impl SpawnerSlot
impl SpawnerSlot
Sourcepub fn set(&self, spawner: SendSpawner)
pub fn set(&self, spawner: SendSpawner)
Fill the slot (last set wins) and wake a ready waiter.
Call before Supervisor::start — or from the other core’s bring-up,
with the supervisor awaiting ready().
Sourcepub fn get(&self) -> Option<SendSpawner>
pub fn get(&self) -> Option<SendSpawner>
The registered spawner, or None while unfilled.
Sourcepub async fn ready(&self) -> SendSpawner
pub async fn ready(&self) -> SendSpawner
Await the slot and return the spawner. The rendezvous primitive: the
supervisor’s bring-up awaits this for a node’s executor: slot before
spawning it (bounded, see Supervisor::start), so a tier filled late — or
from another core — is handled without a race. Returns immediately once the
slot is filled, so any number of late callers are fine (an application can
gate work on the executor being up). While the slot is still empty, at most
one task should be parked here: the underlying Signal holds a single waker,
so a second pre-fill waiter would displace the first.