Structure that describes an event
#include <sys/siginfo.h>
struct sigevent {
int sigev_notify;
#if defined(__WATCOMC__) && !defined(NO_EXT_KEYS)
union {
int sigev_signo;
int sigev_coid;
int sigev_id;
void (*sigev_notify_function)(union sigval);
};
#else
union {
int __sigev_signo;
int __sigev_coid;
int __sigev_id;
void (*__sigev_notify_function)(union sigval);
} __sigev_un1;
# define sigev_signo __sigev_un1.__sigev_signo
# define sigev_coid __sigev_un1.__sigev_coid
# define sigev_id __sigev_un1.__sigev_id
# define sigev_notify_function __sigev_un1.__sigev_notify_function
#endif
union sigval sigev_value;
#if defined(__WATCOMC__) && !defined(NO_EXT_KEYS)
union {
struct {
short sigev_code;
short sigev_priority;
};
pthread_attr_t *sigev_notify_attributes;
};
#else
union {
struct {
short __sigev_code;
short __sigev_priority;
} __st;
pthread_attr_t *__sigev_notify_attributes;
} __sigev_un2;
# define sigev_notify_attributes __sigev_un2.__sigev_notify_attributes
# define sigev_code __sigev_un2.__st.__sigev_code
# define sigev_priority __sigev_un2.__st.__sigev_priority
#endif
};
This structure describes an event. POSIX specifies the basic structure and allows a lot of leeway in extending it. It effectively includes these members (although they aren't all usable at the same time):
| Member | Classification |
|---|---|
| int sigev_notify | POSIX |
| int sigev_signo | POSIX |
| int sigev_coid | QNX Neutrino |
| int sigev_id (not currently used) | QNX Neutrino |
| void sigev_notify_function | POSIX |
| union sigval sigev_value | POSIX |
| short sigev_code | QNX Neutrino |
| short sigev_priority | QNX Neutrino |
| pthread_attr_t *sigev_notify_attributes | POSIX |
The int sigev_notify member indicates how the notification is to occur, as well as which of the other members are used:
![]() |
The library uses some of the extra bits in sigev_notify
for other purposes (see
“Critical threads,”
below).
After initializing an event, don't set sigev_notify directly;
instead, use the SIGEV_SET_TYPE() macro.
For example:
SIGEV_SET_TYPE(&my_event, SIGEV_PULSE) If you want to test the value of this member, use the SIGEV_GET_TYPE() macro. For example, instead of: if( my_event.sigev_notify == SIGEV_PULSE) use: if( SIGEV_GET_TYPE(&my_event) == SIGEV_PULSE) |
The <sys/siginfo.h> file also defines some macros to make initializing the sigevent structure easier. All the macros take a pointer to a sigevent structure as their event argument and set the sigev_notify member to the appropriate value. These macros are QNX Neutrino extensions and are described below.
Send an interrupt notification to a specific thread. No other fields in the structure are used.
The initialization macro is:
SIGEV_INTR_INIT( &event )
Don't send any notification. No other fields in the structure are used.
The initialization macro is:
SIGEV_NONE_INIT( &event )
Send a pulse. The following fields are used:
The initialization macro is:
SIGEV_PULSE_INIT( &event, coid, priority, code, value )
Send a signal to a process. The following fields are used:
The initialization macro is:
SIGEV_SIGNAL_INIT( &event, signal )
If you need to set the sigev_value for a SIGEV_SIGNAL event (for example if SA_SIGINFO is set), you can use this macro:
SIGEV_SIGNAL_VALUE_INIT( &event, signal, value )
This is similar to SIGEV_SIGNAL, except that SIGEV_SIGNAL_CODE also includes a value and a code. The following fields are used:
The initialization macro is:
SIGEV_SIGNAL_CODE_INIT( &event, signal, value, code )
Send a signal to a specific thread, depending on the situation:
In the case of timers, SyncMutexEvent(), and interrupts, if the thread dies before the event gets delivered, the kernel sends the signal to a random thread in the same process.
The following fields are used:
The initialization macro is:
SIGEV_SIGNAL_THREAD_INIT( &event, signal, value, code )
Create a new thread.
![]() |
We don't recommend using this type of event. Pulses are more efficient. |
The following fields are used:
The initialization macro is:
SIGEV_THREAD_INIT( &event, fn, value, attr )
The sigval union is defined as follows:
union sigval {
int sival_int;
void * sival_ptr;
};
Force a thread to become unblocked. No other fields in the structure are used.
The initialization macro is:
SIGEV_UNBLOCK_INIT( &event )
If you're using adaptive partitioning, you can use a sigevent to make a thread run as critical or not.
![]() |
This feature was added in the QNX Neutrino Core OS 6.3.2. For more information, see the Adaptive Partitioning User's Guide. |
After setting up the sigevent structure as appropriate, use these macros to set or clear the hidden bit that makes a thread run as critical or not:
The receiving thread doesn't have to do anything to make itself critical or noncritical; the adaptive partitioning scheduler does this automatically.
![]() |
These macros use hidden bits in the sigev_notify member of the sigevent structure. Don't set or compare this member directly to a value; use the SIGEV_SET_TYPE() or SIGEV_GET_TYPE() macro instead, as described above. |
POSIX, with QNX Neutrino extensions
ds_create(), InterruptAttach(), InterruptAttachEvent(), iofunc_notify(), iofunc_notify_trigger(), ionotify(), lio_listio(), mq_notify(), MsgDeliverEvent(), procmgr_event_notify(), _pulse, SyncMutexEvent(), TimerCreate(), timer_create(), TimerInfo(), TimerTimeout(), timer_timeout()
Interprocess Communication (IPC) chapter of the System Architecture guide
Adaptive Partitioning User's Guide