Send a message to a channel (non-cancellation point)
Synopsis:
#include <sys/neutrino.h>
long MsgSendnc( int coid,
const void* smsg,
size_t sbytes,
void* rmsg,
size_t rbytes );
long MsgSendnc_r( int coid,
const void* smsg,
size_t sbytes,
void* rmsg,
size_t 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.
This number must not exceed SSIZE_MAX, or the function will fail with
EOVERFLOW.
- rmsg
- A pointer to a buffer where the reply can be stored.
- rbytes
- The size of the reply buffer, in bytes.
This number must not exceed SSIZE_MAX, or the function will 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 MsgSendnc() and MsgSendnc_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.
Another difference is that a MsgSendnc*() call that's interrupted to run a
signal handler while SEND-blocked will be automatically restarted, instead of failing with
EINTR like MsgSend*().
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 MsgSendnc() and MsgSendnc_r()
is the way they indicate errors:
- MsgSendnc()
- If an error occurs in MsgSendnc() 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, MsgSendnc() returns -1 and sets errno to the value passed to
MsgError().
- MsgSendnc_r()
- If an error occurs in MsgSendnc_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, MsgSendnc_r() returns the negative of the value
passed to MsgError(). MsgSendnc_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).
- 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 |
No |
Interrupt handler |
No |
Signal handler |
Yes |
Thread |
Yes |
Caveats:
The maximum size for a one-part message depends on the architecture:
- For 32-bit architectures, it's SSIZE_MAX (i.e., 231 − 1) bytes.
- For 64-bit architectures, the API allows up to SSIZE_MAX (i.e., 263 − 1) bytes,
but the virtual address space limits the size to 239 bytes.