Markers & nametable
Two small kernel-level conventions build on top of the plain handle table and ports: markers, which let one port stand in for many logical clients, and the nametable, the one well-known port every process starts with.
Markers
A handle is a bare index; by itself it says nothing about who is on the other end of a
MsgSend or MsgCall beyond “some process holding a handle to this port.” The Stamp syscall lets a
server attach a marker which is an opaque uint32_t badge to a new handle that points at
the same underlying port:
Handle plain = ZuzuPortCreate();
Handle badgeA = ZuzuStamp(plain, 1); // new handle, same port, marker = 1
Handle badgeB = ZuzuStamp(plain, 2); // new handle, same port, marker = 2
plain, badgeA, and badgeB all name the same Port object in the kernel; only the
HandleEntry.marker field differs between them. Stamp is non-consuming and the source
handle must be unmarked (MARKER_NONE, i.e. 0), so markers are always minted from the one
original handle, not from each other.
A server hands out badgeA to one client and badgeB to another (typically via Grant,
since a marked handle is exported the same way any handle is). Both clients MsgSend/MsgCall
into what looks, from their side, like an ordinary port. On the receiving end the server’s
single Waitany loop sees the marker come back in WaitanyResult.marker, so it can tell the
two clients apart without opening a port per client or running a thread per client:
WaitanyResult r;
ZuzuWaitany(handles, count, TIMEOUT_INFINITE, &r);
switch (r.marker) {
case 1: /* handled badgeA's traffic */ break;
case 2: /* handled badgeB's traffic */ break;
}
This is the same rendezvous IPC and the same Waitany multiplexing described in
IPC. Markers add a demultiplexing axis on top,
without adding kernel objects.
Marker 0 is reserved to mean “unmarked” and can never be
stamped onto a handle.
Nametable
Slot 0 of every process’s handle table is reserved for the nametable port: a handle to
the service registry that the nameserver listens on. Every process spawned after that point gets slot 0 pre-populated by sysd, so it can reach the nameserver without any setup of its own. Because slot 0 is a grantable handle to an ordinary port, “the nametable” is the one port that userspace has agreed, by convention, to
always find in the same place. Servers register a name by sending their own (typically
marked) port handle to nameserver over it; clients look a name up the same way. See
sysd for the registration protocol itself.
Pitfalls
A marker only distinguishes handles, not the underlying port: Destroy on any one of
plain, badgeA, or badgeB only frees that handle slot, and the port stays alive as long
as another handle (or the port’s ref count) still holds it.