MsgSend(), MsgSend_r()

Send a message to a channel

Synopsis:

#include <sys/neutrino.h>

int MsgSend( int coid,
             const void* smsg,
             int sbytes,
             void* rmsg,
             int rbytes );

int MsgSend_r( int coid,
               const void* smsg,
               int sbytes,
               void* rmsg,
               int rbytes );

Arguments:

coid
The ID of the connection to the channel to send the message on, which you've established by calling ConnectAttach() or one of its cover functions, such as name_open() or open().
smsg
A pointer to a buffer that contains the message that you want to send.
sbytes
The number of bytes to send.
rmsg
A pointer to a buffer where the reply can be stored.
rbytes
The size of the reply buffer, in bytes.

Library:

libc

Use the -l c option to qcc to link against this library. This library is usually included automatically.

Description:

The MsgSend() and MsgSend_r() kernel calls send a message to a process's channel via the connection identified by coid.

These functions are identical except in the way they indicate errors. See the Returns section for details.

The number of bytes transferred is the minimum of that specified by both the sender and the receiver. The send data isn't allowed to overflow the receive buffer area provided by the receiver. The reply data isn't allowed to overflow the reply buffer area provided.

The sending thread becomes blocked waiting for a reply. If the receiving process has a thread that's RECEIVE-blocked on the channel, the transfer of data into its address space occurs immediately, and the receiving thread is unblocked and made ready to run. The sending thread becomes REPLY-blocked. If there are no waiting threads on the channel, the sending thread becomes SEND-blocked and is placed in a queue (perhaps with other threads). In this case, the actual transfer of data doesn't occur until a receiving thread receives on the channel. At this point, the sending thread becomes REPLY-blocked.


Note: The receiving thread's effective priority might change when you send a message to it. For more information, see Priority inheritance and messages in the Interprocess Communication (IPC) chapter of the System Architecture guide.

MsgSend() is a cancellation point for the ThreadCancel() kernel call; MsgSendnc() isn't.

Blocking states

STATE_SEND
The message has been sent but not yet received. If a thread is waiting to receive the message, this state is skipped and the calling thread goes directly to STATE_REPLY.
STATE_REPLY
The message has been received but not yet replied to. This state may be entered directly, or from STATE_SEND.

Native networking

When a client sends a message to a remote server, the client is effectively sending the message via its local microkernel; the network manager does the actual “work.” The local network manager negotiates with the remote network manager and causes the message to be delivered there. However, the remote manager is the one that actually delivers the message to the server.

This message transfer from the remote manager to the server is accomplished via a special nonblocking message pass.

The only impact on the client is the latency of the message-passing operations. This is purely a function of the network link speed and the overhead associated with the protocol (i.e. lsm-qnet for native networking) that io-pkt* uses.

The client still remains blocked in its MsgSend(), and unblocks only on account of a signal, a kernel timeout, or the completion of its function.

Returns:

The only difference between the MsgSend() and MsgSend_r() functions is the way they indicate errors:

MsgSend()
Success
The value of status from MsgReply*().
-1
An error occurred (errno is set), or the server called MsgError*() (errno is set to the error value passed to MsgError()).
MsgSend_r()
Success
The value of status from MsgReply*().
negative value
An error occurred (errno is NOT set, the value is the negative of a value from the Errors section), or the server called MsgError*() (errno is NOT set, the value is the negative of the error value passed to MsgError()).

Errors:

EBADF
The connection indicated by coid is no longer connected to a channel, or the connection indicated by coid doesn't exist. The channel may have been terminated by the server, or the network manager if it failed to respond to multiple polls.
EFAULT
A fault occurred when the kernel tried to access the buffers provided. This may have occurred on the receive or the reply.
EHOSTDOWN
The host is down (e.g. a send across Qnet failed).
EHOSTUNREACH
Unable to communicate with remote node (e.g. across Qnet).
EINTR
The call was interrupted by a signal.
ESRCH
The server died while the calling thread was SEND-blocked or REPLY-blocked.
ESRVRFAULT
A fault occurred in a server's address space when the kernel tried to access the server's message buffers.
ETIMEDOUT
A kernel timeout unblocked the call. See TimerTimeout().

Classification:

QNX Neutrino

Safety:
Cancellation point Yes
Interrupt handler No
Signal handler Yes
Thread Yes

Caveats:

The maximum size for a one-part message-pass is SSIZE_MAX (i.e., 231 − 1) bytes.

See also:

ConnectAttach(), MsgError(), MsgReceive(), MsgReceivev(), MsgReply(), MsgReplyv(), MsgSendnc(), MsgSendPulse(), MsgSendsv(), MsgSendsvnc(), MsgSendv(), MsgSendvnc(), MsgSendvs(), MsgSendvsnc(), name_open(), TimerTimeout()

Message Passing chapter of Getting Started with QNX Neutrino