Skip to main content

Mailbox

Struct Mailbox 

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

A flow’s inbox, plus (when the owning flow is blocked on Receive / ReceiveMatch / Ask with nothing to read) the parked flow itself.

§Why the flow lives inside its own mailbox while waiting

Internally, a flow is reachable through its super::process::FlowId, which resolves (via [super::directory::Directory]) to this Mailbox. Bytecode does not address by Pid anymore (FlowCap): Send / Ask resolve a Cap to a FlowId first, then look up here. Host crate::Runtime::send still uses FlowId directly (trusted).

Storing the blocked Box<Flow> directly in MailboxInner::parked, behind the same mutex that guards the message queue, turns “deliver a message and wake the receiver if it was waiting” into a single critical section — which is what actually prevents the classic lost-wakeup race:

racing without a shared lock:
  receiver: queue.pop() -> None
  sender:   queue.push(msg); wake(receiver)   // receiver isn't parked yet!
  receiver: park()                            // ...and now sleeps forever

with both steps under one mutex (what this type does):
  receiver: lock; queue.pop() -> None; store self in `parked`; unlock
  sender:   lock; parked.take() -> Some(receiver); unlock; wake(receiver)

Because “check the queue” and “become parked” happen atomically with respect to “push and check for a parked receiver”, there is no window where a message can be pushed without either landing in the queue for a later Receive or immediately waking an already-parked one.

§Selective wait (ReceiveMatch / Ask)

When parked with a non-[WaitFilter::Any] filter, only a hop that satisfies the filter wakes the flow. Other hops are appended to the queue and the waiter stays parked (FIFO skip, never drop).

Implementations§

Source§

impl Mailbox

Source

pub fn new() -> Self

Source

pub fn push(&self, value: Value) -> Result<Delivery, RuntimeError>

Push value. If a flow is currently parked on this mailbox and the hop satisfies its wait filter, it is atomically removed and returned via Delivery::Handoff. Otherwise the hop is queued (and a selective waiter stays parked).

Mutex poison → RuntimeError (fail-closed; do not continue on inconsistent shared state).

Source

pub fn try_pop(&self) -> Result<Option<Value>, RuntimeError>

Non-blocking pop of the front hop (classic Receive).

Source

pub fn try_pop_match(&self, tag: u16) -> Result<Option<Value>, RuntimeError>

Non-blocking selective pop by application tag (ReceiveMatch).

Source

pub fn park( &self, flow: Box<Flow>, ) -> Result<Result<(), Box<Flow>>, RuntimeError>

Atomically re-check the queue and, if still empty, store flow as parked (classic Receive — any hop wakes).

Outer Result is infrastructure (mutex poison). Inner Result is the lost-wakeup race: Err(flow) means a message arrived between the worker’s try_pop and this call — resume immediately with the stashed pending message rather than parking forever.

Source

pub fn park_match( &self, flow: Box<Flow>, tag: u16, ) -> Result<Result<(), Box<Flow>>, RuntimeError>

Like park, but only a hop with Message.tag == tag ends the wait. Non-matching hops already in the queue are left untouched (FIFO skip).

Source

pub fn take_parked(&self) -> Result<Option<Box<Flow>>, RuntimeError>

Attempt to take a timed-out parked flow back out, used by the timer wheel when a ReceiveTimeout deadline fires. Returns None if the flow was already woken by a Send in the meantime.

Trait Implementations§

Source§

impl Default for Mailbox

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> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

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

Source§

type Error = !

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.