Install, poll, or remove a notification handler
Synopsis:
#include <sys/iofunc.h>
int iofunc_notify( resmgr_context_t *ctp,
io_notify_t *msg,
iofunc_notify_t *nop,
int trig,
const int *notifycounts,
int *armed );
Arguments:
- ctp
- A pointer to a
resmgr_context_t
structure that the resource-manager library uses to pass context information
between functions.
- msg
- A pointer to the
io_notify_t
structure that contains
the message that the resource manager received; see below.
- nop
- An array of three
iofunc_notify_t
structures that represent, in order, the input, output, and out-of-band notification
lists; see below.
Generally, this structure is maintained by the resource manager
within an extended attributes structure.
- trig
- A bitmask indicating which sources are currently satisfied, and could
cause a trigger to occur. This bitmask is any combination of
_NOTIFY_COND_INPUT, _NOTIFY_COND_OUTPUT and
_NOTIFY_COND_OBAND.
You typically set this value, based on the conditions in effect at
the time of the call.
- notifycounts
- NULL, or an array of three integers representing, in order,
the number of elements that must be present in the input, output, and out-of-band queues
in order for the event to be triggered.
Note that if any condition is met, nothing is armed.
Only if none of the conditions are met, does the
event get armed in accordance with the notifycounts parameter. If this
parameter is NULL, a value of 1 is assumed for all counts.
- armed
- NULL, or a pointer to a location where the function can
store a 1 to indicate that a notification entry is armed, or a
0 otherwise.
Library:
libc
Use the -l c option to
qcc
to link against this library.
This library is usually included automatically.
Description:
The POSIX layer helper function iofunc_notify() is used by a
resource manager to implement notification.
This routine examines the message that the resource manager received (passed
in the msg argument), and determines what action the client
code is attempting to perform:
- _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_CONDARM
- If the conditions aren't met, arm the event and return EAGAIN;
if the conditions are met, return a one-part IOV with the flags
field set to indicate which conditions are available.
- _NOTIFY_ACTION_POLL
- Return a one-part IOV with the flags field set to indicate
which conditions are available.
The caller should return
(_RESMGR_NPARTS(1))
to the resource manager library, which returns a one-part
message to the client.
- _NOTIFY_ACTION_POLLARM
- Similar to _NOTIFY_ACTION_POLL, with the
additional characteristic of arming the event if none of the
conditions is met.
- _NOTIFY_ACTION_TRANARM
- For each of the sources specified, create a notification entry
and store the client's struct sigevent event structure in it.
Note that only one transition arm is allowed at a time per device.
If the client specifies an event of SIGEV_NONE, the
action is to disarm.
When the event is triggered, the notification is automatically disarmed.
io_notify_t structure
The io_notify_t structure holds the _IO_NOTIFY or _IO_NOTIFY64
message received by the resource manager:
struct _io_notify {
uint16_t type;
uint16_t combine_len;
int32_t action;
int32_t flags;
struct __sigevent32 event;
/* Following fields only valid if (flags & _NOTIFY_COND_EXTEN) */
int32_t mgr[2]; /* For use by manager */
int32_t flags_extra_mask;
int32_t flags_exten;
int32_t nfds;
int32_t fd_first;
int32_t nfds_ready;
int64_t timo;
/* struct pollfd fds[nfds]; */
};
struct _io_notify64 {
uint16_t type;
uint16_t combine_len;
int32_t action;
int32_t flags;
struct __sigevent32 old_event;
/* Following fields only valid if (flags & _NOTIFY_COND_EXTEN) */
int32_t mgr[2]; /* For use by manager */
int32_t flags_extra_mask;
int32_t flags_exten;
int32_t nfds;
int32_t fd_first;
int32_t nfds_ready;
int64_t timo;
union {
struct __sigevent32 event32;
struct __sigevent64 event64;
};
/* struct pollfd fds[nfds]; */
};
struct _io_notify_reply {
uint32_t zero;
uint32_t flags; /* actions above */
int32_t flags2; /* flags above */
struct __sigevent32 event;
/* Following fields only updated by new managers (if valid) */
int32_t mgr[2]; /* For use by manager */
int32_t flags_extra_mask;
int32_t flags_exten;
int32_t nfds;
int32_t fd_first;
int32_t nfds_ready;
int64_t timo;
/* struct pollfd fds[nfds]; */
};
struct _io_notify_reply64 {
uint32_t zero;
uint32_t flags; /* actions */
int32_t flags2; /* flags above */
struct __sigevent32 old_event;
/* Following fields only updated by new managers (if valid) */
int32_t mgr[2]; /* For use by manager */
int32_t flags_extra_mask;
int32_t flags_exten;
int32_t nfds;
int32_t fd_first;
int32_t nfds_ready;
int64_t timo;
union {
struct __sigevent32 event32;
struct __sigevent64 event64;
};
/* struct pollfd fds[nfds]; */
};
typedef union {
struct _io_notify i;
struct _io_notify64 i64;
struct _io_notify_reply o;
struct _io_notify_reply64 o64;
} io_notify_t;
The I/O message structures are unions of an input message (coming to the
resource manager) and an output or reply message (going back to the client).
The i member (of type _io_notify) and
the i64 member (of type _io_notify64)
contain the following members:
- type
- _IO_NOTIFY or _IO_NOTIFY64.
- combine_len
- If the message is a combine message, _IO_COMBINE_FLAG
is set in this member.
For more information, see
Combine Messages
chapter of Writing a Resource Manager.
- action
- _NOTIFY_ACTION_CONDARM, _NOTIFY_ACTION_EDGEARM, _NOTIFY_ACTION_POLL,
_NOTIFY_ACTION_POLLARM, or _NOTIFY_ACTION_TRANARM, as described above.
- flags
- One of the following:
- _NOTIFY_COND_INPUT — this condition is met when
there are one or more units of input data available
(i.e., clients can now issue reads).
- _NOTIFY_COND_OUTPUT —
this condition is met when there's room in the output buffer
for one or more units of data (i.e. clients can now issue writes).
- _NOTIFY_COND_OBAND —
the condition is met when one or more units of out-of-band data are
available.
- _NOTIFY_COND_EXTEN — the conditions are defined with the extended flags
in the flags_exten member; used internally.
- mgr[2]
- For use by the manager.
- flags_extra_mask
- A mask for removing the extra flags from the flags member.
- flags_exten
- A bitset of the extended _NOTIFY_CONDE_* flags; used internally.
- nfds
- The number of entries in the array of pollfd structures that follows the message.
- fd_first
- The index of the first entry in the array of pollfd structures that has
a non-negative file descriptor.
- nfds_ready
- The number of file descriptors that are ready.
- timo
- The time-out, in nanoseconds.
- event32 or event64
- A pointer to a
sigevent
structure that defines the event that the resource manager is to deliver
once a condition is met.
As indicated by the comment, if _NOTIFY_COND_EXTEN is set in the flags,
the message is followed by an array of pollfd structures.
For more information about this structure, see
poll().
The o member (of type _io_notify_reply) and
the o64 member (of type _io_notify_reply64)
contain the following members:
- flags
- Which of the conditions were triggered; see the flags for
_io_notify, above.
It also includes updated copies of the extended fields.
iofunc_notify_t structure
The iofunc_notify_t structure is defined in
<sys/iofunc.h> as follows:
typedef struct _iofunc_notify {
int cnt;
struct _iofunc_notify_event *list;
} iofunc_notify_t;
The members of the iofunc_notify_t structure include:
- cnt
- The smallest cnt member in the list; see below.
- list
- A pointer to a linked list of iofunc_notify_event_t structures that represent one
of the input, output, and out-of-band notification lists.
CAUTION:
To avoid race conditions in multi-threaded server processes, you must serialize access to each
iofunc_notify_t structure. For more information, see the note about
locking iofunc_notify_t structures
in
Handling ionotify(), poll(), and select() in
Writing a Resource Manager.
The iofunc_notify_event_t structure is defined as:
typedef struct _iofunc_notify_event {
struct _iofunc_notify_event *next;
int rcvid;
int scoid;
int cnt;
struct __sigevent32 old_event;
unsigned flags;
int coid;
union {
struct sigevent event;
struct __sigevent32 event32;
struct __sigevent64 event64;
};
} iofunc_notify_event_t;
The members of the iofunc_notify_event_t structure include:
- next
- A pointer to the next element in the list.
- rcvid
- The receive ID of the client to notify.
- scoid
- The server connection ID.
- cnt
- The number of bytes available.
Some clients, such as io-char, may want a sufficiently large
amount of data to be available before they access it.
- old_event
- Maintained for backwards compatibility.
- flags
- A bitwise OR of zero or more of the following:
- _NOTIFY_COND_EXTEN, plus any extended (_NOTIFY_CONDE_*) bits; used internally
- _NOTIFY_EDGEEVENT — an edge condition is being masked for
_NOTIFY_ACTION_EDGEARM
- coid
- The connection ID.
- event
- A pointer to a
sigevent
structure that defines the event that the resource manager is to deliver
once a condition is met.
The sys/iofunc.h file also defines the following macros
that work with the arrays of iofunc_notify_t structures:
- #define IOFUNC_NOTIFY_DISARM(__nop, __index) ...
- Disarm the list specified by __index in __nop.
- #define IOFUNC_NOTIFY_INIT(__nop) ...
- Initialize the three lists in __nop.
Returns:
- -1
- Success; the resource manager library should return a one-part IOV to
the client.
- EAGAIN
- The action was _NOTIFY_ACTION_CONDARM, and the conditions weren't met.
- EBUSY
- A notification was already armed for this resource, and this library function
enforces a restriction of one per resource.
- EINVAL
- Invalid action.
- ENOMEM
- There wasn't enough memory available to create an iofunc_notify_event_t structure.
Classification:
QNX Neutrino
Safety: |
|
Cancellation point |
No |
Interrupt handler |
No |
Signal handler |
Yes |
Thread |
Yes |