MsgReceivev(), MsgReceivev_r()

Wait for a message or pulse on a channel

Synopsis:

#include <sys/neutrino.h>

int MsgReceivev( int chid,
                 const iov_t * riov,
                 size_t rparts,
                 struct _msg_info * info );

int MsgReceivev_r( int chid,
                   const iov_t * riov,
                   size_t rparts,
                   struct _msg_info * info );

Arguments:

chid
The ID of a channel that you established by calling ChannelCreate(), or -1 to dissociate the thread from the last channel it received on (see Server boost in the Interprocess Communication chapter of the System Architecture guide).
riov
An array of buffers where the function can store the received data. The sum of the IOV buffer lengths must not exceed SSIZE_MAX, or the function will behave unpredictably; for instance, it may fail with EOVERFLOW.
rparts
The number of elements in the 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.
info
NULL, or a pointer to a _msg_info structure where the function can store additional information about the message.

Library:

libc

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

Description:

The MsgReceivev() and MsgReceivev_r() kernel calls wait for a message or pulse to arrive on the channel identified by chid and place the received data in the array of buffers pointed to by riov.

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 received data isn't allowed to overflow the receive buffer area provided.

Note: The first buffer of the IOV (input/output vector) must be big enough to contain a pulse. If it isn't, the functions indicate an error of EFAULT.

If a message is waiting on the channel when you call MsgReceivev(), the calling thread won't block, and the message is immediately copied. If a message isn't waiting, the calling thread enters the RECEIVE-blocked state until a message arrives.

If multiple messages are sent to a channel without a thread waiting to receive them, the messages are queued in priority order.

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

If you pass a non-NULL pointer for info, the functions store additional information about the message and the thread that sent it in the _msg_info structure that info points to. You can get this information later by calling MsgInfo().

On success, MsgReceivev() and MsgReceivev_r() return:

>0
A message was received; the value returned is a rcvid (receive identifier). You'll use the rcvid with other Msg*() kernel calls to interact with and reply to the sending thread. MsgReceivev() changes the state of the sending thread to REPLY-blocked when the message is received. When you use MsgReply*() to reply to the received message, the sending thread is made ready again. The rcvid encodes the sending thread's ID and a local connection ID.
0
A pulse was received; the IOV's first buffer contains a pulse message of type _pulse. When a pulse is received, the kernel space allocated to hold it is immediately released. The _msg_info structure isn't updated.
Note: Don't reply to a pulse.

Blocking states

STATE_RECEIVE
There's no message waiting.

Returns:

On success, both functions return a positive rcvid if they received a message, or EOK if they received a pulse. The only difference between MsgReceivev() and MsgReceivev_r() is the way they indicate errors:

MsgReceivev()
If an error occurs, this function returns -1 and sets errno.
MsgReceivev_r()
If an error occurs, this function may return the negative of any value from the Errors section. This function does NOT set errno, even on success.

Errors:

EFAULT
A fault occurred when the kernel tried to access the buffers provided. Because the OS accesses the sender's buffers only when MsgReceivev() is called, a fault could occur in the sender if the sender's buffers are invalid. If a fault occurs when accessing the sender's buffers, the sender receives an EFAULT, and MsgReceivev() doesn't unblock.

This error also occurs if the kernel tries to deliver a pulse to the server, but the size of the receive buffer is less than the size of a struct _pulse. The pulse is lost in this case.

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 channel indicated by chid doesn't exist.
ETIMEDOUT
A kernel timeout unblocked the call. See TimerTimeout().

Classification:

QNX Neutrino

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