MsgPause(), MsgPause_r()

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 pointNo
Interrupt handlerNo
Signal handlerYes
ThreadYes
Page updated: