Skip to content

Commit 0ac0f47

Browse files
committed
Allow setting kevent_flags on struct sigevent
Depends on rust-lang/libc#2813 Blocks tokio-rs/tokio#4728
1 parent 5dedbc7 commit 0ac0f47

File tree

2 files changed

+51
-48
lines changed

2 files changed

+51
-48
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ targets = [
2727
]
2828

2929
[dependencies]
30-
libc = { version = "0.2.126", features = [ "extra_traits" ] }
30+
libc = { git = "https://github.com/asomers/libc.git", rev = "d50a0f348caed16dfea7004ee2ec2adee6209f2b", features = [ "extra_traits" ] }
3131
bitflags = "1.1"
3232
cfg-if = "1.0"
3333
pin-utils = { version = "0.1.0", optional = true }

src/sys/signal.rs

Lines changed: 50 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1029,8 +1029,7 @@ pub enum SigevNotify {
10291029
/// structure of the queued signal.
10301030
si_value: libc::intptr_t
10311031
},
1032-
// Note: SIGEV_THREAD is not implemented because libc::sigevent does not
1033-
// expose a way to set the union members needed by SIGEV_THREAD.
1032+
// Note: SIGEV_THREAD is not implemented, but could be if desired.
10341033
/// Notify by delivering an event to a kqueue.
10351034
#[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
10361035
#[cfg_attr(docsrs, doc(cfg(all())))]
@@ -1040,6 +1039,18 @@ pub enum SigevNotify {
10401039
/// Will be contained in the kevent's `udata` field.
10411040
udata: libc::intptr_t
10421041
},
1042+
/// Notify by delivering an event to a kqueue, with optional event flags set
1043+
#[cfg(target_os = "freebsd")]
1044+
#[cfg_attr(docsrs, doc(cfg(all())))]
1045+
#[cfg(feature = "event")]
1046+
SigevKeventFlags {
1047+
/// File descriptor of the kqueue to notify.
1048+
kq: RawFd,
1049+
/// Will be contained in the kevent's `udata` field.
1050+
udata: libc::intptr_t,
1051+
/// Flags that will be set on the delivered event. See `kevent(2)`.
1052+
flags: crate::sys::event::EventFlag
1053+
},
10431054
/// Notify by delivering a signal to a thread.
10441055
#[cfg(any(target_os = "freebsd", target_os = "linux"))]
10451056
#[cfg_attr(docsrs, doc(cfg(all())))]
@@ -1062,10 +1073,7 @@ mod sigevent {
10621073
#![any(feature = "aio", feature = "signal")]
10631074

10641075
use std::mem;
1065-
use std::ptr;
10661076
use super::SigevNotify;
1067-
#[cfg(any(target_os = "freebsd", target_os = "linux"))]
1068-
use super::type_of_thread_id;
10691077

10701078
/// Used to request asynchronous notification of the completion of certain
10711079
/// events, such as POSIX AIO and timers.
@@ -1093,53 +1101,48 @@ mod sigevent {
10931101
// See https://github.com/nix-rust/nix/issues/1441
10941102
#[cfg_attr(target_os = "fuchsia", allow(invalid_value))]
10951103
pub fn new(sigev_notify: SigevNotify) -> SigEvent {
1096-
let mut sev = unsafe { mem::MaybeUninit::<libc::sigevent>::zeroed().assume_init() };
1097-
sev.sigev_notify = match sigev_notify {
1098-
SigevNotify::SigevNone => libc::SIGEV_NONE,
1099-
SigevNotify::SigevSignal{..} => libc::SIGEV_SIGNAL,
1104+
let mut sev: libc::sigevent = unsafe { mem::zeroed() };
1105+
match sigev_notify {
1106+
SigevNotify::SigevNone => {
1107+
sev.sigev_notify = libc::SIGEV_NONE;
1108+
},
1109+
SigevNotify::SigevSignal{signal, si_value} => {
1110+
sev.sigev_notify = libc::SIGEV_SIGNAL;
1111+
sev.sigev_signo = signal as libc::c_int;
1112+
sev.sigev_value.sival_ptr = si_value as *mut libc::c_void
1113+
},
11001114
#[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
1101-
SigevNotify::SigevKevent{..} => libc::SIGEV_KEVENT,
1115+
SigevNotify::SigevKevent{kq, udata} => {
1116+
sev.sigev_notify = libc::SIGEV_KEVENT;
1117+
sev.sigev_signo = kq;
1118+
sev.sigev_value.sival_ptr = udata as *mut libc::c_void;
1119+
},
11021120
#[cfg(target_os = "freebsd")]
1103-
SigevNotify::SigevThreadId{..} => libc::SIGEV_THREAD_ID,
1104-
#[cfg(all(target_os = "linux", target_env = "gnu", not(target_arch = "mips")))]
1105-
SigevNotify::SigevThreadId{..} => libc::SIGEV_THREAD_ID,
1106-
#[cfg(all(target_os = "linux", target_env = "uclibc"))]
1107-
SigevNotify::SigevThreadId{..} => libc::SIGEV_THREAD_ID,
1108-
#[cfg(any(all(target_os = "linux", target_env = "musl"), target_arch = "mips"))]
1109-
SigevNotify::SigevThreadId{..} => 4 // No SIGEV_THREAD_ID defined
1110-
};
1111-
sev.sigev_signo = match sigev_notify {
1112-
SigevNotify::SigevSignal{ signal, .. } => signal as libc::c_int,
1113-
#[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
1114-
SigevNotify::SigevKevent{ kq, ..} => kq,
1115-
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
1116-
SigevNotify::SigevThreadId{ signal, .. } => signal as libc::c_int,
1117-
_ => 0
1118-
};
1119-
sev.sigev_value.sival_ptr = match sigev_notify {
1120-
SigevNotify::SigevNone => ptr::null_mut::<libc::c_void>(),
1121-
SigevNotify::SigevSignal{ si_value, .. } => si_value as *mut libc::c_void,
1122-
#[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
1123-
SigevNotify::SigevKevent{ udata, .. } => udata as *mut libc::c_void,
1124-
#[cfg(any(target_os = "freebsd", target_os = "linux"))]
1125-
SigevNotify::SigevThreadId{ si_value, .. } => si_value as *mut libc::c_void,
1126-
};
1127-
SigEvent::set_tid(&mut sev, &sigev_notify);
1121+
#[cfg(feature = "event")]
1122+
SigevNotify::SigevKeventFlags{kq, udata, flags} => {
1123+
sev.sigev_notify = libc::SIGEV_KEVENT;
1124+
sev.sigev_signo = kq;
1125+
sev.sigev_value.sival_ptr = udata as *mut libc::c_void;
1126+
sev._sigev_un._kevent_flags = flags.bits();
1127+
},
1128+
#[cfg(target_os = "freebsd")]
1129+
SigevNotify::SigevThreadId{signal, thread_id, si_value} => {
1130+
sev.sigev_notify = libc::SIGEV_THREAD_ID;
1131+
sev.sigev_signo = signal as libc::c_int;
1132+
sev.sigev_value.sival_ptr = si_value as *mut libc::c_void;
1133+
sev._sigev_un._threadid = thread_id;
1134+
}
1135+
#[cfg(target_os = "linux")]
1136+
SigevNotify::SigevThreadId{signal, thread_id, si_value} => {
1137+
sev.sigev_notify = libc::SIGEV_THREAD_ID;
1138+
sev.sigev_signo = signal as libc::c_int;
1139+
sev.sigev_value.sival_ptr = si_value as *mut libc::c_void;
1140+
sev._sigev_un._tid = thread_id;
1141+
}
1142+
}
11281143
SigEvent{sigevent: sev}
11291144
}
11301145

1131-
#[cfg(any(target_os = "freebsd", target_os = "linux"))]
1132-
fn set_tid(sev: &mut libc::sigevent, sigev_notify: &SigevNotify) {
1133-
sev.sigev_notify_thread_id = match *sigev_notify {
1134-
SigevNotify::SigevThreadId { thread_id, .. } => thread_id,
1135-
_ => 0 as type_of_thread_id
1136-
};
1137-
}
1138-
1139-
#[cfg(not(any(target_os = "freebsd", target_os = "linux")))]
1140-
fn set_tid(_sev: &mut libc::sigevent, _sigev_notify: &SigevNotify) {
1141-
}
1142-
11431146
/// Return a copy of the inner structure
11441147
pub fn sigevent(&self) -> libc::sigevent {
11451148
self.sigevent

0 commit comments

Comments
 (0)