Each task has its own space of port rights. Port rights are named with
positive integers. Except for the reserved values
MACH_PORT_NULL (0)1 and
MACH_PORT_DEAD (~0), this is a full 32-bit
name space. When the kernel chooses a name for a new right, it is free
to pick any unused name (one which denotes no right) in the space.
There are five basic kinds of rights: receive rights, send rights, send-once rights, port-set rights, and dead names. Dead names are not capabilities. They act as place-holders to prevent a name from being otherwise used.
A port is destroyed, or dies, when its receive right is deallocated. When a port dies, send and send-once rights for the port turn into dead names. Any messages queued at the port are destroyed, which deallocates the port rights and out-of-line memory in the messages.
Tasks may hold multiple user-references for send rights and dead names. When a task receives a send right which it already holds, the kernel increments the right's user-reference count. When a task deallocates a send right, the kernel decrements its user-reference count, and the task only loses the send right when the count goes to zero.
Send-once rights always have a user-reference count of one, although a port can have multiple send-once rights, because each send-once right held by a task has a different name. In contrast, when a task holds send rights or a receive right for a port, the rights share a single name.
A message body can carry port rights; the
msgtl_name) field in a type descriptor specifies the type of
port right and how the port right is to be extracted from the caller.
MACH_PORT_DEAD are always
valid in place of a port right in a message body. In a sent message,
msgt_name values denote port rights:
If a message carries a send or send-once right, and the port dies while
the message is in transit, then the receiving task will get
MACH_PORT_DEAD instead of a right. The following
msgt_name values in a received message indicate that it carries
MACH_MSG_TYPE_MOVE_SEND. The message carried a send right. If the receiving task already has send and/or receive rights for the port, then that name for the port will be reused. Otherwise, the new right will have a new name. If the task already has send rights, it gains a user reference for the right (unless this would cause the user-reference count to overflow). Otherwise, it acquires the send right, with a user-reference count of one.
MACH_MSG_TYPE_MOVE_SEND_ONCE. The message carried a send-once right. The right will have a new name.
MACH_MSG_TYPE_MOVE_RECEIVE. The message carried a receive right. If the receiving task already has send rights for the port, then that name for the port will be reused. Otherwise, the right will have a new name. The make-send count of the receive right is reset to zero, but the port retains other attributes like queued messages, extant send and send-once rights, and requests for port-destroyed and no-senders notifications.
When the kernel chooses a new name for a port right, it can choose any
name, other than
is not currently being used for a port right or dead name. It might
choose a name which at some previous time denoted a port right, but is
 In the Hurd system, we don't make
the assumption that
MACH_PORT_NULL is zero and evaluates to
false, but rather compare port names to