Let's take a quick look at how you fill in the struct sigevent structure.
Regardless of the notification scheme you choose, you'll need to fill in a struct sigevent structure. For the details, see the C Library Reference; here's a simplified version:
struct sigevent {
int sigev_notify;
union {
int __sigev_signo;
int __sigev_coid;
int __sigev_id;
void (*__sigev_notify_function)(union sigval);
volatile unsigned *__sigev_addr;
} __sigev_un1;
union sigval sigev_value;
union {
struct {
short __sigev_code;
short __sigev_priority;
} __st;
pthread_attr_t *__sigev_notify_attributes;
int __sigev_memop;
} __sigev_un2;
};
The first field you have to fill in is the sigev_notify member. This determines the notification type you've selected:
Since we're going to be using the struct sigevent with timers, we're concerned only with the SIGEV_PULSE, SIGEV_SIGNAL* and SIGEV_THREAD values for sigev_notify; we'll see the other types as mentioned in the list above.
To send a pulse when the timer fires, set the sigev_notify field to SIGEV_PULSE and provide some extra information:
| Field | Value and meaning |
|---|---|
| sigev_coid | Send the pulse to the channel associated with this connection ID. |
| sigev_value | A 32-bit value that gets sent to the connection identified in the sigev_coid field. |
| sigev_code | An 8-bit value that gets sent to the connection identified in the sigev_coid field. |
| sigev_priority | The pulse's delivery priority. The value zero is not allowed (too many people were getting bitten by running at priority zero when they got a pulse—priority zero is what the idle task runs at, so effectively they were competing with QNX Neutrino's IDLE process and not getting much CPU time :-)). |
Note that the sigev_coid could be a connection to any channel (usually, though not necessarily, the channel associated with the process that's initiating the event).
To send a signal, set the sigev_notify field to one of:
For SIGEV_SIGNAL*, the additional fields you'll have to fill are:
| Field | Value and meaning |
|---|---|
| sigev_signo | Signal number to send (from <signal.h>, e.g., SIGALRM). |
| sigev_code | An 8-bit code (if using SIGEV_SIGNAL_CODE or SIGEV_SIGNAL_THREAD). |
To create a thread whenever the timer fires, set the sigev_notify field to SIGEV_THREAD and fill these fields:
| Field | Value and meaning |
|---|---|
| sigev_notify_function | Address of void * function that accepts a void * to be called when the event triggers. |
| sigev_value | Value passed as the parameter to the sigev_notify_function() function. |
| sigev_notify_attributes | Thread attributes structure (see the Processes and Threads chapter, under The thread attributes structure for details). |
(QNX Neutrino 7.0.4 or later) In order to use an event of type SIGEV_THREAD, your process must have the PROCMGR_AID_SIGEV_THREAD ability enabled. For more information, see procmgr_ability().
There are some convenience macros in <sys/siginfo.h> to make filling in the notification structures easier (see the entry for sigevent in the QNX Neutrino C Library Reference):