Pause the processing of a message
Synopsis:
#include <sys/neutrino.h>
int MsgPause( int rcvid,
unsigned cookie );
int MsgPause_r( int rcvid,
unsigned cookie );
Arguments:
- rcvid
- The receive ID that MsgReceive*() returned when you received the
message.
- cookie
- A value for the kernel to pass back to the resource manager with the
_PULSE_CODE_RESTART pulse when the situation has been resolved.
Note that the
cookie argument must be the
rcvid if
message pausing support is implemented by setting up an
iofunc unpause
handler.
The
cookie can be different if the default
iofunc
handlers haven't been set up. However, the internal unpause handler is always first to access
the argument and expects the
cookie to be the
rcvid.
Refer to
The
receive ID (a.k.a. the client cookie) for more information on the
relationship between the two arguments above.
Library:
libc
Use the -l c option to
qcc
to link against this library. This library is usually included automatically.
Description:
The MsgPause() and MsgPause_r() kernel calls pause a message.
The thread associated with the rcvid must be reply-blocked on a channel that's
owned by the calling process.
Message pausing is used to handle a deadlock (
EDEADLK) error.
This type of error could be caused by such things as:
- writing to a memory-mapped file from a buffer mapped in from a memory-mapped file that's
managed by the same server
- reading from a memory-mapped file
The deadlock could make (for example) a thread of the client application block on the server,
a thread from the server block on procnto, and a procnto
thread block on the server.
If your server is not a resource manager, here's an overview of how it would use these
functions:
-
When the server creates its channel by calling
ChannelCreate(),
it sets _NTO_CHF_MSG_PAUSING
to inform the kernel that it supports pausing a message that would otherwise cause a deadlock.
- If a MsgRead*(), MsgWrite*(), or
MsgReply*() call indicates an error of EDEADLK, the server
calls MsgPause() to pause the message passing.
- After MsgPause() returns, the server goes back to its
MsgReceive() loop for handling messages or pulses.
- Later, when the kernel resolves things, it sends a _PULSE_CODE_RESTART to the
server with the cookie from the MsgPause() call included as the pulse value.
- The server uses the cookie passed with the pulse to identify the operation and calls
MsgCurrent() to inform the kernel that it's resuming the processing of the
message.
- The server tries again to read, write, or reply to the message.
Blocking states
None. If priority inheritance causes the priority of the calling thread to drop, other threads may run.
Returns:
The only difference between these functions is the way they indicate errors.
- MsgPause()
- If successful, this function returns EOK. If an error occurs, it returns -1 and sets
errno.
- MsgPause_r()
- If successful, this function returns EOK. This function does NOT set errno, even on success.
If an error occurs, it may return any value from the Errors section.
Errors:
- EINVAL
- The thread associated with the rcvid already has a message paused.
- ENOMEM
- There wasn't enough memory available.
- ESRCH
- The thread associated with the rcvid isn't in STATE_REPLY.
Classification:
QNX Neutrino
Safety: |
|
Cancellation point |
No |
Interrupt handler |
No |
Signal handler |
Yes |
Thread |
Yes |