The receive operation dequeues a message from a port. The receiving task acquires the port rights and out-of-line memory regions carried in the message.
rcv_name argument specifies a port or port set from which to
receive. If a port is specified, the caller must possess the receive
right for the port and the port must not be a member of a port set. If
no message is present, then the call blocks, subject to the
If a port set is specified, the call will receive a message sent to any
of the member ports. It is permissible for the port set to have no
member ports, and ports may be added and removed while a receive from
the port set is in progress. The received message can come from any of
the member ports which have messages, with the proviso that a member
port with messages will not be indefinitely starved. The
msgh_local_port field in the received message header specifies
from which port in the port set the message came.
rcv_size argument specifies the size of the caller's message
mach_msg call will not receive a message larger than
rcv_size. Messages that are too large are destroyed, unless the
MACH_RCV_LARGE option is used.
The destination and reply ports are reversed in a received message
msgh_local_port field names the destination port,
from which the message was received, and the
field names the reply port right. The bits in
msgh_bits are also
MACH_MSGH_BITS_LOCAL bits have the value
MACH_MSG_TYPE_PORT_SEND if the message was sent to a send right,
and the value
MACH_MSG_TYPE_PORT_SEND_ONCE if was sent to a
send-once right. The
MACH_MSGH_BITS_REMOTE bits describe the
reply port right.
A received message can contain port rights and out-of-line memory. The
msgh_local_port field does not receive a port right; the act of
receiving the message destroys the send or send-once right for the
destination port. The msgh_remote_port field does name a received port
right, the reply port right, and the message body can carry port rights
and memory if
MACH_MSGH_BITS_COMPLEX is present in msgh_bits.
Received port rights and memory should be consumed or deallocated in
In almost all cases,
msgh_local_port will specify the name of a
receive right, either
rcv_name or if
rcv_name is a port
set, a member of
rcv_name. If other threads are concurrently
manipulating the receive right, the situation is more complicated. If
the receive right is renamed during the call, then
msgh_local_port specifies the right's new name. If the caller
loses the receive right after the message was dequeued from it, then
mach_msg will proceed instead of returning
MACH_RCV_PORT_DIED. If the receive right was destroyed, then
MACH_PORT_DEAD. If the receive
right still exists, but isn't held by the caller, then
Received messages are stamped with a sequence number, taken from the
port from which the message was received. (Messages received from a
port set are stamped with a sequence number from the appropriate member
port.) Newly created ports start with a zero sequence number, and the
sequence number is reset to zero whenever the port's receive right moves
between tasks. When a message is dequeued from the port, it is stamped
with the port's sequence number and the port's sequence number is then
incremented. The dequeue and increment operations are atomic, so that
multiple threads receiving messages from a port can use the
msgh_seqno field to reconstruct the original order of the
These options modify
MACH_RCV_MSG is not
also specified, they are ignored.
MACH_RCV_TIMED_OUT. A zero timeout is legitimate.
mach_msgcall will return
MACH_RCV_INTERRUPTEDif a software interrupt aborts the call. Otherwise, the receive operation will be retried.
rcv_size, then the message remains queued instead of being destroyed. The call returns
MACH_RCV_TOO_LARGEand the actual size of the message is returned in the
msgh_sizefield of the message header.
The receive operation can generate the following return codes. These return codes imply that the call did not dequeue a message:
rcv_namespecified a receive right which was moved into a port set during the call.
MACH_RCV_LARGE, and the message was larger than
rcv_size. The message is left queued, and its actual size is returned in the
msgh_sizefield of the message buffer.
These return codes imply that a message was dequeued and destroyed:
MACH_RCV_NOTIFY, the notify argument did not denote a valid receive right.
MACH_RCV_LARGE, a message larger than
rcv_sizewas dequeued and destroyed.
In these situations, when a message is dequeued and then destroyed, the
reply port and all port rights and memory in the message body are
destroyed. However, the caller receives the message's header, with all
fields correct, including the destination port but excepting the reply
port, which is
These return codes imply that a message was received:
Resource shortages can occur after a message is dequeued, while
transferring port rights and out-of-line memory regions to the receiving
mach_msg call returns
MACH_RCV_BODY_ERROR in this situation. These return codes always
carry extra bits (bitwise-ored) that indicate the nature of the resource
If a resource shortage prevents the reception of a port right, the port
right is destroyed and the caller sees the name
If a resource shortage prevents the reception of an out-of-line memory
region, the region is destroyed and the caller receives a zero address.
In addition, the
msgtl_size) field in the
data's type descriptor is changed to zero. If a resource shortage
prevents the reception of out-of-line memory carrying port rights, then
the port rights are always destroyed if the memory region can not be
received. A task never receives port rights or memory regions that it
isn't told about.
 If MACH_RCV_TIMEOUT is used without MACH_RCV_INTERRUPT, then the timeout duration might not be accurate. When the call is interrupted and automatically retried, the original timeout is used. If interrupts occur frequently enough, the timeout interval might never expire.