@@ -1042,8 +1042,7 @@ pub enum SigevNotify {
10421042 /// structure of the queued signal.
10431043 si_value: libc:: intptr_t
10441044 } ,
1045- // Note: SIGEV_THREAD is not implemented because libc::sigevent does not
1046- // expose a way to set the union members needed by SIGEV_THREAD.
1045+ // Note: SIGEV_THREAD is not implemented, but could be if desired.
10471046 /// Notify by delivering an event to a kqueue.
10481047 #[ cfg( any( target_os = "dragonfly" , target_os = "freebsd" ) ) ]
10491048 #[ cfg_attr( docsrs, doc( cfg( all( ) ) ) ) ]
@@ -1053,8 +1052,24 @@ pub enum SigevNotify {
10531052 /// Will be contained in the kevent's `udata` field.
10541053 udata: libc:: intptr_t
10551054 } ,
1055+ /// Notify by delivering an event to a kqueue, with optional event flags set
1056+ #[ cfg( target_os = "freebsd" ) ]
1057+ #[ cfg_attr( docsrs, doc( cfg( all( ) ) ) ) ]
1058+ #[ cfg( feature = "event" ) ]
1059+ SigevKeventFlags {
1060+ /// File descriptor of the kqueue to notify.
1061+ kq: RawFd ,
1062+ /// Will be contained in the kevent's `udata` field.
1063+ udata: libc:: intptr_t,
1064+ /// Flags that will be set on the delivered event. See `kevent(2)`.
1065+ flags: crate :: sys:: event:: EventFlag
1066+ } ,
10561067 /// Notify by delivering a signal to a thread.
1057- #[ cfg( any( target_os = "freebsd" , target_os = "linux" ) ) ]
1068+ #[ cfg( any(
1069+ target_os = "freebsd" ,
1070+ target_env = "gnu" ,
1071+ target_env = "uclibc" ,
1072+ ) ) ]
10581073 #[ cfg_attr( docsrs, doc( cfg( all( ) ) ) ) ]
10591074 SigevThreadId {
10601075 /// Signal to send
@@ -1079,10 +1094,7 @@ mod sigevent {
10791094 #![ any( feature = "aio" , feature = "signal" ) ]
10801095
10811096 use std:: mem;
1082- use std:: ptr;
10831097 use super :: SigevNotify ;
1084- #[ cfg( any( target_os = "freebsd" , target_os = "linux" ) ) ]
1085- use super :: type_of_thread_id;
10861098
10871099 /// Used to request asynchronous notification of the completion of certain
10881100 /// events, such as POSIX AIO and timers.
@@ -1107,53 +1119,54 @@ mod sigevent {
11071119 /// `SIGEV_SIGNAL`. That field is part of a union that shares space with the
11081120 /// more genuinely useful `sigev_notify_thread_id`
11091121 pub fn new( sigev_notify: SigevNotify ) -> SigEvent {
1110- let mut sev = unsafe { mem:: MaybeUninit :: <libc:: sigevent>:: zeroed( ) . assume_init( ) } ;
1111- sev. sigev_notify = match sigev_notify {
1112- SigevNotify :: SigevNone => libc:: SIGEV_NONE ,
1113- SigevNotify :: SigevSignal { ..} => libc:: SIGEV_SIGNAL ,
1122+ let mut sev: libc:: sigevent = unsafe { mem:: zeroed( ) } ;
1123+ match sigev_notify {
1124+ SigevNotify :: SigevNone => {
1125+ sev. sigev_notify = libc:: SIGEV_NONE ;
1126+ } ,
1127+ SigevNotify :: SigevSignal { signal, si_value} => {
1128+ sev. sigev_notify = libc:: SIGEV_SIGNAL ;
1129+ sev. sigev_signo = signal as libc:: c_int;
1130+ sev. sigev_value. sival_ptr = si_value as * mut libc:: c_void
1131+ } ,
11141132 #[ cfg( any( target_os = "dragonfly" , target_os = "freebsd" ) ) ]
1115- SigevNotify :: SigevKevent { ..} => libc:: SIGEV_KEVENT ,
1133+ SigevNotify :: SigevKevent { kq, udata} => {
1134+ sev. sigev_notify = libc:: SIGEV_KEVENT ;
1135+ sev. sigev_signo = kq;
1136+ sev. sigev_value. sival_ptr = udata as * mut libc:: c_void;
1137+ } ,
11161138 #[ cfg( target_os = "freebsd" ) ]
1117- SigevNotify :: SigevThreadId { ..} => libc:: SIGEV_THREAD_ID ,
1118- #[ cfg( all( target_os = "linux" , target_env = "gnu" , not( target_arch = "mips" ) ) ) ]
1119- SigevNotify :: SigevThreadId { ..} => libc:: SIGEV_THREAD_ID ,
1120- #[ cfg( all( target_os = "linux" , target_env = "uclibc" , not( target_arch = "mips" ) ) ) ]
1121- SigevNotify :: SigevThreadId { ..} => libc:: SIGEV_THREAD_ID ,
1122- #[ cfg( any( all( target_os = "linux" , target_env = "musl" ) , target_arch = "mips" ) ) ]
1123- SigevNotify :: SigevThreadId { ..} => 4 // No SIGEV_THREAD_ID defined
1124- } ;
1125- sev. sigev_signo = match sigev_notify {
1126- SigevNotify :: SigevSignal { signal, .. } => signal as libc:: c_int,
1127- #[ cfg( any( target_os = "dragonfly" , target_os = "freebsd" ) ) ]
1128- SigevNotify :: SigevKevent { kq, ..} => kq,
1129- #[ cfg( any( target_os = "linux" , target_os = "freebsd" ) ) ]
1130- SigevNotify :: SigevThreadId { signal, .. } => signal as libc:: c_int,
1131- _ => 0
1132- } ;
1133- sev. sigev_value. sival_ptr = match sigev_notify {
1134- SigevNotify :: SigevNone => ptr:: null_mut:: <libc:: c_void>( ) ,
1135- SigevNotify :: SigevSignal { si_value, .. } => si_value as * mut libc:: c_void,
1136- #[ cfg( any( target_os = "dragonfly" , target_os = "freebsd" ) ) ]
1137- SigevNotify :: SigevKevent { udata, .. } => udata as * mut libc:: c_void,
1138- #[ cfg( any( target_os = "freebsd" , target_os = "linux" ) ) ]
1139- SigevNotify :: SigevThreadId { si_value, .. } => si_value as * mut libc:: c_void,
1140- } ;
1141- SigEvent :: set_tid( & mut sev, & sigev_notify) ;
1139+ #[ cfg( feature = "event" ) ]
1140+ SigevNotify :: SigevKeventFlags { kq, udata, flags} => {
1141+ sev. sigev_notify = libc:: SIGEV_KEVENT ;
1142+ sev. sigev_signo = kq;
1143+ sev. sigev_value. sival_ptr = udata as * mut libc:: c_void;
1144+ sev. _sigev_un. _kevent_flags = flags. bits( ) ;
1145+ } ,
1146+ #[ cfg( target_os = "freebsd" ) ]
1147+ SigevNotify :: SigevThreadId { signal, thread_id, si_value} => {
1148+ sev. sigev_notify = libc:: SIGEV_THREAD_ID ;
1149+ sev. sigev_signo = signal as libc:: c_int;
1150+ sev. sigev_value. sival_ptr = si_value as * mut libc:: c_void;
1151+ sev. _sigev_un. _threadid = thread_id;
1152+ }
1153+ #[ cfg( all(
1154+ any(
1155+ target_env = "gnu" ,
1156+ target_env = "uclibc" ,
1157+ ) ,
1158+ not( target_arch = "mips" )
1159+ ) ) ]
1160+ SigevNotify :: SigevThreadId { signal, thread_id, si_value} => {
1161+ sev. sigev_notify = libc:: SIGEV_THREAD_ID ;
1162+ sev. sigev_signo = signal as libc:: c_int;
1163+ sev. sigev_value. sival_ptr = si_value as * mut libc:: c_void;
1164+ sev. _sigev_un. _tid = thread_id;
1165+ }
1166+ }
11421167 SigEvent { sigevent: sev}
11431168 }
11441169
1145- #[ cfg( any( target_os = "freebsd" , target_os = "linux" ) ) ]
1146- fn set_tid( sev: & mut libc:: sigevent, sigev_notify: & SigevNotify ) {
1147- sev. sigev_notify_thread_id = match * sigev_notify {
1148- SigevNotify :: SigevThreadId { thread_id, .. } => thread_id,
1149- _ => 0 as type_of_thread_id
1150- } ;
1151- }
1152-
1153- #[ cfg( not( any( target_os = "freebsd" , target_os = "linux" ) ) ) ]
1154- fn set_tid( _sev: & mut libc:: sigevent, _sigev_notify: & SigevNotify ) {
1155- }
1156-
11571170 /// Return a copy of the inner structure
11581171 pub fn sigevent( & self ) -> libc:: sigevent {
11591172 self . sigevent
0 commit comments