ionotify()
Arm a resource manager
Synopsis:
#include <unistd.h>
#include <sys/iomsg.h>
int ionotify ( int fd,
int action,
int flags,
const struct sigevent *event );
Arguments:
- fd
- The file descriptor associated with the resource manager that you want to get notifications from.
- action
- The type of arming action to take; see
Actions,
below. - flags
- The types of conditions that can be checked for notification; see
Flags,
below. - event
- A pointer to a sigevent structure that defines the event that you want the resource manager to send as a notification, or NULL to disarm a notification.
Library:
libc
Use the -l c option to qcc to link against this library. This library is usually included automatically.
Description:
The ionotify() function arms the resource manager associated with fd to send the event notification event. The event is sent when a condition specified by a combination of action and flags occurs. The application must register the event by calling MsgRegisterEvent() with the fd passed to ionotify(). This function corresponds to the Linux epoll() function and BSD's kqueue().
The QNX OS implementations of select() and poll() are built on top of ionotify(). Generally, you use ionotify() if you want to combine input from file descriptors with QNX OS messaging in the same process. Use poll() when you're handling multiple file descriptors from sockets, pipes, serial ports, and so on.
Flags
The flags argument specifies the types of conditions that can be checked for notification. Each resource manager maintains a different context for each notification condition. Only those notification bits specified are affected. In the following example, the second call to ionotify() doesn't affect the first, since it specifies a different notification:
ionotify( fd, _NOTIFY_ACTION_POLLARM,
_NOTIFY_COND_INPUT, &event );
ionotify( fd, _NOTIFY_ACTION_POLLARM,
_NOTIFY_COND_OUTPUT, &event );
The conditions specified by flags are:
- _NOTIFY_COND_OBAND
- Out-of-band data is available, an exceptional condition has occurred, or an error has occurred, all as defined by the resource manager.
- _NOTIFY_COND_OUTPUT
- This usually means there's room in the output buffer for more data. More generally, it means that a write() call will return without blocking (but may return an error). The amount of room available needed to satisfy this condition depends on the resource manager. Some resource managers may default to an empty output buffer, while others may choose some percentage of the buffer empty.
- _NOTIFY_COND_INPUT
- This usually means there's input data available. More generally, it means that a read() call will return without blocking (but may return an error). May be further overloaded (e.g., a listen() socket has a connection available to accept(). The amount of data available defaults to 1. For a character device such as a serial port, this would be a character. For a POSIX message queue, it would be a message. Each resource manager selects an appropriate object.
- _NOTIFY_COND_EXTEN
- The conditions are defined with some extended flags; used internally.
The method for changing the default number for _NOTIFY_COND_OUTPUT and _NOTIFY_COND_INPUT depends on the device. For example, character special devices can call readcond().
For resource managers that support both an edited and raw mode, the mode should be set to raw to ensure proper operation of ionotify().
The above flags are located in the top bits of flags. They are defined by _NOTIFY_COND_MASK.
In the case of an asynchronous notification using the passed
event, such as a QNX OS pulse or queued realtime signal, the
32-bit value in event->sigev_value.sival_int
is
returned to you unmodified, unless you've selected the
SI_NOTIFY code, in which case the top bits (defined by
_NOTIFY_COND_MASK) are set to the active notifications.
In this case, you should limit the sival_int to the mask defined by
_NOTIFY_DATA_MASK.
For example, the POSIX select() function specifies SI_NOTIFY and uses the allowable data bits of sival_int as a serial number.
Actions
The action argument specifies the type of arming action to take. When a condition is armed, the resource manager monitors it and, when met, delivers event using MsgDeliverEvent(). When an event is delivered, it's always disarmed except where noted below.
Note that for transition arming (as specified by an action of _NOTIFY_ACTION_TRANARM, only one notification of that type can be outstanding per device. When the transition arm fires, it's removed.
Each action is designed to support a specific notification type as follows:
- _NOTIFY_ACTION_CONDARM
- If the conditions aren't met, arm the event and give an error of EAGAIN; if the conditions are met, indicate which of them are available.
- _NOTIFY_ACTION_EDGEARM
- Conditions are considered as met only if a change occurs since the last call to
ionotify(..., _NOTIFY_ACTION_EDGEARM, ...)
. Met conditions are returned; a notification is armed for unmet conditions. - _NOTIFY_ACTION_POLL
- This action does a poll of the notification conditions specified
by flags. It never arms an event, and it cancels
all other asynchronous event notifications
set up by a previous call to ionotify(). This also allows it
to be used as a simple
disarm
call.Returns active conditions as requested by flags.
- _NOTIFY_ACTION_POLLARM
- This action does a poll in the same way as
_NOTIFY_ACTION_POLL. However, if none of the
conditions specified in flags are present then each
condition specified in flags is armed. If any
condition is met, none of the conditions are
armed. The POSIX select() function uses
ionotify() with this action.
Returns active conditions as requested by flags.
- _NOTIFY_ACTION_TRANARM
- This action arms for transitions of the notification conditions specified
by flags. A transition is defined as a
data transition from empty to nonempty on input.
Its use on output isn't defined.
Note that if there is data available when this call is used, a data transition won't occur.
To generate an event using this type of notification, you
must arm the event and then drain the input using a nonblocking read.
After this point, new input data causes the event to be delivered.
The mq_notify() function uses ionotify() with
this action.
Since this arms for a transition, the return value is always zero.
Note:There's a limit of one notification per message queue or resource manager object. If a notification was already armed for the specified resource, ionotify() indicates an error of EBUSY.
You can use the _NOTIFY_ACTION_POLLARM or _NOTIFY_ACTION_POLL action to generate events that are level- as opposed to transition-oriented.
When an action is armed in a resource manager, it remains armed until one of the following occurs:
- a thread sets a new action (this disarms any current action and possibly arms a new action)
- the event is delivered
- a thread closes the file descriptor (fd), in which case all pending notifications for that fd are delivered and then disarmed
Returns:
Active conditions as requested by flags. In the case of a transition action, a zero is returned. If an error occurs, -1 is returned (errno is set).
Errors:
- EAGAIN
- The action was _NOTIFY_ACTION_CONDARM, and the conditions weren't met.
- EBADF
- The connection indicated by fd doesn't exist, or fd is no longer connected to a channel.
- EBUSY
- A notification was already armed for this resource; this function enforces a restriction of one per message queue or resource manager.
- EFAULT
- A fault occurred when the kernel tried to access the buffers provided. This may have occurred on the receive or the reply.
- EINTR
- The call was interrupted by a signal.
- ENOMEM
- The resource manager couldn't allocate a notify entry to save the request.
- ENOSYS
- The requested action isn't supported by this resource manager.
- ESRVRFAULT
- A fault occurred in a server's address space while accessing the server's message buffers. This may have occurred on the receive or the reply.
- ETIMEDOUT
- A kernel timeout unblocked the call; see TimerTimeout().
Classification:
Safety: | |
---|---|
Cancellation point | No |
Signal handler | Yes |
Thread | Yes |