Skip to content

Mailbox

New to the concept? See Tools — Mailbox first.

Moves handles between Masters.

const mailbox = @import("matryoshka").mailbox;
const Mbox = @import("matryoshka").Mbox;

// typical usage:
var slot: polynode.Slot = &event.poly;
try inbox.send(&slot);              // slot is now null
try inbox.receive(&slot, null);     // slot is now non-null

Types

pub const Mbox = struct { ... };

Application code holds *Mbox and calls methods on it.

A mailbox is also a PolyNode. toPoly/fromPoly carry it through another
mailbox or pool. A mailbox can be:

  • sent through another mailbox
  • stored in pools
  • embedded into larger structures

Same rules as application items.

The struct fields are internal. Use the methods.


What a mailbox never does

The mailbox keeps items. It never touches them. No inspection, no copy, no
free — it
allocates and frees exactly one thing, itself.

So every item it holds goes back to a caller:

edge who ends up holding the item
receive, try_receive the receiver
send, send_oob returning error.Closed the sender — the slot is unchanged
receive_batch the caller, as a list
close the caller, as a list

Releasing them is the caller's job. Free them, or put them back into a pool
— which one is knowledge the mailbox does not have and never had.

Contrast with Pool, which does touch items, through
your hooks.


new

pub fn new(io: Io, alloc: std.mem.Allocator, slot: *polynode.Slot) !void
  • Creates a mailbox and puts it in the Slot. It returns no pointer.
  • The Slot must be empty on entry.
  • The Slot is left unchanged if the creation fails.
  • Take the pointer out with Mbox.moveFromSlot(&slot), on the next line.
  • Stores io internally.
pub fn destroy_slot(slot: *polynode.Slot, alloc: std.mem.Allocator) void
  • Frees the mailbox in the Slot, and empties the Slot.
  • An empty Slot is a no-op. So is a second call on the same Slot.
  • A Slot holding another type is a programming error (panic).
  • Must be closed first, as destroy requires.