Go to the first, previous, next, last section, table of contents.
The mach_msg call handles port rights in a message header
atomically. Port rights and out-of-line memory in a message body do not
enjoy this atomicity guarantee. The message body may be processed
front-to-back, back-to-front, first out-of-line memory then port rights,
in some random order, or even atomically.
For example, consider sending a message with the destination port
specified as MACH_MSG_TYPE_MOVE_SEND and the reply port specified
as MACH_MSG_TYPE_COPY_SEND. The same send right, with one
user-reference, is supplied for both the msgh_remote_port and
msgh_local_port fields. Because mach_msg processes the
message header atomically, this succeeds. If msgh_remote_port
were processed before msgh_local_port, then mach_msg would
return MACH_SEND_INVALID_REPLY in this situation.
On the other hand, suppose the destination and reply port are both
specified as MACH_MSG_TYPE_MOVE_SEND, and again the same send
right with one user-reference is supplied for both. Now the send
operation fails, but because it processes the header atomically,
mach_msg can return either MACH_SEND_INVALID_DEST or
MACH_SEND_INVALID_REPLY.
For example, consider receiving a message at the same time another
thread is deallocating the destination receive right. Suppose the reply
port field carries a send right for the destination port. If the
deallocation happens before the dequeuing, then the receiver gets
MACH_RCV_PORT_DIED. If the deallocation happens after the
receive, then the msgh_local_port and the msgh_remote_port
fields both specify the same right, which becomes a dead name when the
receive right is deallocated. If the deallocation happens between the
dequeue and the receive, then the msgh_local_port and
msgh_remote_port fields both specify MACH_PORT_DEAD.
Because the header is processed atomically, it is not possible for just
one of the two fields to hold MACH_PORT_DEAD.
The MACH_RCV_NOTIFY option provides a more likely example.
Suppose a message carrying a send-once right reply port is received with
MACH_RCV_NOTIFY at the same time the reply port is destroyed. If
the reply port is destroyed first, then msgh_remote_port
specifies MACH_PORT_DEAD and the kernel does not generate a
dead-name notification. If the reply port is destroyed after it is
received, then msgh_remote_port specifies a dead name for which
the kernel generates a dead-name notification. It is not possible to
receive the reply port right and have it turn into a dead name before
the dead-name notification is requested; as part of the message header
the reply port is received atomically.
Go to the first, previous, next, last section, table of contents.