Go to the first, previous, next, last section, table of contents.
The send operation queues a message to a port. The message carries a copy of the caller's data. After the send, the caller can freely modify the message buffer or the out-of-line memory regions and the message contents will remain unchanged.
Message delivery is reliable and sequenced. Messages are not lost, and messages sent to a port, from a single thread, are received in the order in which they were sent.
If the destination port's queue is full, then several things can happen.
If the message is sent to a send-once right (msgh_remote_port
carries a send-once right), then the kernel ignores the queue limit and
delivers the message. Otherwise the caller blocks until there is room
in the queue, unless the MACH_SEND_TIMEOUT
or
MACH_SEND_NOTIFY
options are used. If a port has several blocked
senders, then any of them may queue the next message when space in the
queue becomes available, with the proviso that a blocked sender will not
be indefinitely starved.
These options modify MACH_SEND_MSG
. If MACH_SEND_MSG
is
not also specified, they are ignored.
MACH_SEND_TIMEOUT
MACH_SEND_TIMED_OUT
. A zero timeout is legitimate.
MACH_SEND_NOTIFY
MACH_SEND_WILL_NOTIFY
is returned, and a msg-accepted
notification is requested. If MACH_SEND_TIMEOUT
is also
specified, then MACH_SEND_NOTIFY
doesn't take effect until the
timeout interval elapses.
With MACH_SEND_NOTIFY
, a task can forcibly queue to a send right
one message at a time. A msg-accepted notification is sent to the the
notify port when another message can be forcibly queued. If an attempt
is made to use MACH_SEND_NOTIFY
before then, the call returns a
MACH_SEND_NOTIFY_IN_PROGRESS
error.
The msg-accepted notification carries the name of the send right. If
the send right is deallocated before the msg-accepted notification is
generated, then the msg-accepted notification carries the value
MACH_PORT_NULL
. If the destination port is destroyed before the
notification is generated, then a send-once notification is generated
instead.
MACH_SEND_INTERRUPT
mach_msg
call will return
MACH_SEND_INTERRUPTED
if a software interrupt aborts the call.
Otherwise, the send operation will be retried.
MACH_SEND_CANCEL
MACH_RCV_NOTIFY
option. It should only be used as an optimization.
The send operation can generate the following return codes. These return codes imply that the call did nothing:
MACH_SEND_MSG_TOO_SMALL
MACH_SEND_NO_BUFFER
MACH_SEND_INVALID_DATA
MACH_SEND_INVALID_HEADER
msgh_bits
value was invalid.
MACH_SEND_INVALID_DEST
msgh_remote_port
value was invalid.
MACH_SEND_INVALID_REPLY
msgh_local_port
value was invalid.
MACH_SEND_INVALID_NOTIFY
MACH_SEND_CANCEL
, the notify argument did not denote a
valid receive right.
These return codes imply that some or all of the message was destroyed:
MACH_SEND_INVALID_MEMORY
MACH_SEND_INVALID_RIGHT
MACH_SEND_INVALID_TYPE
MACH_SEND_MSG_TOO_SMALL
These return codes imply that the message was returned to the caller with a pseudo-receive operation:
MACH_SEND_TIMED_OUT
MACH_SEND_INTERRUPTED
MACH_SEND_INVALID_NOTIFY
MACH_SEND_NOTIFY
, the notify argument did not denote a
valid receive right.
MACH_SEND_NO_NOTIFY
MACH_SEND_NOTIFY_IN_PROGRESS
These return codes imply that the message was queued:
MACH_SEND_WILL_NOTIFY
MACH_MSG_SUCCESS
Some return codes, like MACH_SEND_TIMED_OUT
, imply that the
message was almost sent, but could not be queued. In these situations,
the kernel tries to return the message contents to the caller with a
pseudo-receive operation. This prevents the loss of port rights or
memory which only exist in the message. For example, a receive right
which was moved into the message, or out-of-line memory sent with the
deallocate bit.
The pseudo-receive operation is very similar to a normal receive operation. The pseudo-receive handles the port rights in the message header as if they were in the message body. They are not reversed. After the pseudo-receive, the message is ready to be resent. If the message is not resent, note that out-of-line memory regions may have moved and some port rights may have changed names.
The pseudo-receive operation may encounter resource shortages. This is
similar to a MACH_RCV_BODY_ERROR
return code from a receive
operation. When this happens, the normal send return codes are
augmented with the MACH_MSG_IPC_SPACE
, MACH_MSG_VM_SPACE
,
MACH_MSG_IPC_KERNEL
, and MACH_MSG_VM_KERNEL
bits to
indicate the nature of the resource shortage.
The queueing of a message carrying receive rights may create a circular loop of receive rights and messages, which can never be received. For example, a message carrying a receive right can be sent to that receive right. This situation is not an error, but the kernel will garbage-collect such loops, destroying the messages and ports involved.
Go to the first, previous, next, last section, table of contents.