Structure that describes an event
#include <sys/siginfo.h>
union __sigval32 {
        int                     sival_int;
        _Uintptr32t     sival_ptr;
};
union __sigval64 {
        int                     sival_int;
        _Uintptr64t     sival_ptr;
};
union sigval {
    int         sival_int;
    void       *sival_ptr;
};
struct __sigevent32 {
        int                             sigev_notify;
        union {
                int                     __sigev_signo;
                int                     __sigev_coid;
                int                     __sigev_id;
                _Uintptr32t             __sigev_notify_function;
                _Uintptr32t             __sigev_addr;
                unsigned                __sigev_handle;
        } __sigev_un1;
        union __sigval32 sigev_value;
        union {
                struct {
                        short           __sigev_code;
                        short           __sigev_priority;
                } __st;
                _Uintptr32t             __sigev_notify_attributes;
                int                     __sigev_memop;
        } __sigev_un2;
};
struct __sigevent64 {
        int                             sigev_notify;
        union {
                int                     __sigev_signo;
                int                     __sigev_coid;
                int                     __sigev_id;
                _Uintptr64t             __sigev_notify_function;
                _Uintptr64t             __sigev_addr;
                unsigned                __sigev_handle;
        } __sigev_un1;
        union __sigval64 sigev_value;
        union {
                struct {
                        short           __sigev_code;
                        short           __sigev_priority;
                } __st;
                _Uintptr64t             __sigev_notify_attributes;
                int                     __sigev_memop;
        } __sigev_un2;
};
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;
                unsigned                __sigev_handle;
        } __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;
};
# 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
# define sigev_addr                __sigev_un1.__sigev_addr
# define sigev_handle              __sigev_un1.__sigev_handle
# 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
# define sigev_memop               __sigev_un2.__sigev_memop
The sigevent 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 | 
| volatile unsigned *sigev_addr | QNX Neutrino | 
| unsigned sigev_handle | QNX Neutrino | 
| union sigval sigev_value | POSIX | 
| short sigev_code | QNX Neutrino | 
| short sigev_priority | QNX Neutrino | 
| pthread_attr_t *sigev_notify_attributes | POSIX | 
| int sigev_memop | QNX Neutrino | 
The value of sigev_notify indicates how the notification is to occur and which of the other members are used:
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)
(QNX Neutrino 7.0.1 or later) The kernel uses the sigev_handle field for registered events, which are more secure than regular sigevents. For more information, see the entry for MsgRegisterEvent(), as well as Events in the Interprocess Communication (IPC) chapter of the System Architecture guide.
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.
SIGEV_INTR (QNX Neutrino extension)
Send an interrupt notification to a specific thread, depending on the situation:
No other fields in the structure are used.
The initialization macro is:
SIGEV_INTR_INIT( &event )
SIGEV_MEMORY (QNX Neutrino extension)
(QNX Neutrino 6.6 or later) Directly manipulate a location in memory. The following fields are used:
For the SIGEV_MEM_BIT* operations, the bits that are set in the value indicate which bits to set, clear, or toggle in the location in memory.
The initialization macro is:
SIGEV_MEMORY_INIT( &event, addr, value, operation )
procmgr_event_notify_add( PROCMGR_EVENT_CONFSTR, my_sigevent );and then call confstr(CS_TIMEZONE, ...) once and cache the result. The process manager will notify the client by setting a memory location when the time zone string might have changed. If somebody wants to get the time zone, and the memory location hasn't been set, the local cached value is still current. If the memory location is set, they need to call confstr(CS_TIMEZONE, ...) again.
SIGEV_NONE (POSIX)
Don't send any notification. No other fields in the structure are used.
The initialization macro is:
SIGEV_NONE_INIT( &event )
SIGEV_PULSE (QNX Neutrino extension)
Send a pulse. The following fields are used:
The priority of the pulse must be in the range for the target process, or (in QNX Neutrino 6.6 or later) that process must have the PROCMGR_AID_PRIORITY ability enabled (see procmgr_ability()). In QNX Neutrino 6.6 or later, if procnto was started with an s appended to the -P option, then out-of-range priority requests use the maximum allowed value instead of resulting in an error.
The initialization macros are:
Store the value in sigev_value.sival_ptr.
(QNX Neutrino 7.0 or later) Store the value in sigev_value.sival_int and set the hidden SIGEV_FLAG_SIVAL_INT bit in sigev_notify.
(QNX Neutrino 7.0 or later) Store the value in sigev_value.sival_ptr.
SIGEV_SIGNAL (POSIX)
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 one of these macros instead of SIGEV_SIGNAL_INIT():
Store the value in sigev_value.sival_ptr.
(QNX Neutrino 7.0 or later) Store the value in sigev_value.sival_int and set the hidden SIGEV_FLAG_SIVAL_INT bit in sigev_notify.
(QNX Neutrino 7.0 or later) Store the value in sigev_value.sival_ptr.
SIGEV_SIGNAL_CODE (QNX Neutrino extension)
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 macros are:
Store value in sigev_value.sival_ptr.
(QNX Neutrino 7.0 or later) Store the value in sigev_value.sival_int and set the hidden SIGEV_FLAG_SIVAL_INT bit in sigev_notify.
(QNX Neutrino 7.0 or later) Store the value in sigev_value.sival_ptr.
These macros store the code in sigev_code.
SIGEV_SIGNAL_THREAD (QNX Neutrino extension)
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 )
SIGEV_THREAD (POSIX)
Create a new thread.
(QNX Neutrino 7.0.4 or later) In order to register or use an event of type SIGEV_THREAD, your process must have the PROCMGR_AID_SIGEV_THREAD ability enabled. For more information, see procmgr_ability().
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;
};
SIGEV_UNBLOCK (QNX Neutrino extension)
Force a thread to become unblocked. No other fields in the structure are used.
The initialization macro is:
SIGEV_UNBLOCK_INIT( &event )
Hidden bits (QNX Neutrino extension)
After you've set up the sigevent structure as appropriate, you can use some extra bits in sigev_notify for other purposes. The bits and their associated macros include:
if (event.sigev_notify & SIGEV_FLAG_CODE_UPDATEABLE)
{ // may update event before delivering }
else
{ // should not update event before delivering } 
  The actual update depends on the server. For information about the updated information for kernel events, see procmgr_event_notify_add().
if (event.sigev_notify & SIGEV_FLAG_UPDATEABLE)
{ // may update event before delivering }
else
{ // should not update event before delivering } 
  You'll typically use struct sigevent, unless your program needs to work with sigevents from 32- and 64-bit programs, in which case you'll also have to work with struct __sigevent32 and struct __sigevent64.
Since a sigevent might be passed between 32- and 64-bit programs, we've defined a SIGEV_64BIT flag that indicates which type of sigevent it is. We OR this flag into the sigev_notify types. For example, in addition to SIGEV_SIGNAL, we have SIGEV_SIGNAL32 and SIGEV_SIGNAL64:
Some programs use SIGEV_NONE to identify an empty sigevent. For compatibility, SIGEV_NONE is always the same as SIGEV_NONE32, no matter which architecture you compile for.
If your program stores sigevents from 32- and 64-bit programs, you should replace struct sigevent with a union:
union {
   struct sigevent ev;
   struct __sigevent32 ev32;
   struct __sigevent64 ev64;
};
Your code can then check ev.sigev_notify, determine whether the sigevent is from a 32- or 64-bit program, and then use the ev32 or ev64 structure, as appropriate.