MsgSendv(), MsgSendv_r()

Updated: April 19, 2023

Send a message to a channel

Synopsis:

#include <sys/neutrino.h>

long MsgSendv( int coid,
               const iov_t* siov,
               size_t sparts,
               const iov_t* riov,
               size_t rparts );

long MsgSendv_r( int coid,
                 const iov_t* siov,
                 size_t sparts,
                 const iov_t* riov,
                 size_t rparts );

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().
siov
An array of buffers that contains the message that you want to send. The sum of the IOV buffer lengths must not exceed SSIZE_MAX, or the function will fail with EOVERFLOW.
sparts
The number of elements in the siov array. This number must not exceed 524288, or the function will fail with EOVERFLOW. If the number exceeds SSIZE_MAX, the function will behave unpredictably; for instance, it may fail with EOVERFLOW.
riov
An array of buffers where the reply can be stored. The sum of the IOV buffer lengths must not exceed SSIZE_MAX, or the function will fail with EOVERFLOW.
rparts
The number of elements in the riov array. This number must not exceed 524288, or the function will fail with EOVERFLOW. If the number exceeds SSIZE_MAX, the function will behave unpredictably; for instance, it may fail with EOVERFLOW.

Library:

libc

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

Description:

The MsgSendv() and MsgSendv_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.

It's quite common to send two-part messages consisting of a fixed header and a buffer of data. The MsgSendv() function gathers the data from the send list into a logically contiguous message and transfers it to the receiver. The receiver doesn't need to specify the same number or size of buffers. The data is laid down filling each entry as required. The same applies to the replied data.

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.

MsgSendv() is a cancellation point for the ThreadCancel() kernel call; MsgSendvnc() 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.

Returns:

The only difference between MsgSendv() and MsgSendv_r() is the way they indicate errors:

MsgSendv()
If an error occurs in MsgSendv() itself, the function returns -1 and sets errno to a value from the Errors section. If the receiving thread calls MsgError() to unblock the sending thread, MsgSendv() returns -1 and sets errno to the value passed to MsgError().
MsgSendv_r()
If an error occurs in MsgSendv_r() itself, the function returns the negative of a value from the Errors section. If the receiving thread calls MsgError() to unblock the sending thread, MsgSend() returns the negative of the value passed to MsgError(). MsgSendv_r() does NOT set errno, even on success.

Any other return value is the status from MsgReply*().

Errors:

If the message passing itself failed, the errors include the following:

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.
EOVERFLOW
The sum of the IOV lengths exceeds SSIZE_MAX, or the number of parts exceeds 524288.
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().

If the message passing succeeded, but the server called MsgError(), the error code can be whatever the server wants it to be.

Classification:

QNX Neutrino

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