Skip to main content

Module ipc

Module ipc 

Source
Expand description

Messages between services: sending one, receiving one, and what the failures mean.

§The model in four sentences

A service owns one endpoint with a bounded queue (16 messages, CLAUDE.md 8.5). A send COPIES the bytes into the receiver’s queue and returns; it does not wait for the receiver to look at them. So a successful send means queued, not processed - if you need to know it was acted on, the protocol has to say so, which is what crate::call is for. And a message can carry a capability, which MOVES: the sender no longer holds it afterwards.

§Why every failure here is worth reading rather than retrying

The three you will actually meet say different things and want different answers:

  • Error::Unreachable - the peer died, or its name does not resolve right now. Nothing happened. The name is stable even though the instance is not (CLAUDE.md invariant 11), so the answer is cap::reacquire and then retry - not a sleep.
  • Error::Busy - the peer is alive and its queue is full. Nothing happened. Congestion is transient; pace and retry, and do not go looking for a peer that never went away.
  • Error::InvalidInput - the message exceeds one page. Nothing will make that work; send less.

A fourth appears only when you hand a capability away with send_granting:

  • Error::PermissionDenied - the capability you tried to send does not carry GRANT. Nothing moved, so it is still yours and the slot is still yours to reclaim. This is the first of the three checks CLAUDE.md 8.5 asks of every transfer, and it is the one a compiler cannot make for you.

§The deadlock rule, which the kernel will not save you from

If A and B both send to each other, at least one direction MUST use try_send. A blocking send into a full queue waits, and two services waiting on each other wait forever. The kernel does not detect this and does not break it (CLAUDE.md 8.9) - the supervisor’s starvation watchdog is a last resort, not a design.

Modules§

exact
The kernel’s exact refusal, for the few programs whose job is to tell refusals apart.

Structs§

Message
An IPC message as seen by service code.

Constants§

MAX_BYTES
The largest message body, in bytes: one page (CLAUDE.md 8.5).

Functions§

park
Sleep forever, having nothing left to do.
peer
A capability to a peer this service was wired to at spawn, by name.
peer_at
A capability to a peer this service was WIRED TO at spawn, by position.
recv
Block until a message arrives on this service’s endpoint.
recv_within
Block for a message, giving up after secs.
recv_within_ms
recv_within, bounded in MILLISECONDS.
reply
Answer a request on the reply capability its client sent, then give that capability back.
send
Send to a service by NAME, blocking if its queue is full.
send_granting
Send a message that CARRIES a capability, giving it away.
send_to
Send through a capability you already hold, rather than resolving a name.
take_sent_cap
The capability that arrived embedded in the message just received, if any.
try_recv
Take a message if one is already waiting, without blocking.
try_send
Send to a service by NAME, refusing rather than waiting if its queue is full.
try_send_to
Non-blocking send_to.