Skip to content

Commit 255a6f6

Browse files
committed
Allow setting kevent_flags on struct sigevent
Also, disallow using SigevNotify::SigevThreadId on musl. I don't think it ever worked. Depends on rust-lang/libc#2813 Blocks tokio-rs/tokio#4728
1 parent 5dedbc7 commit 255a6f6

File tree

2 files changed

+61
-49
lines changed

2 files changed

+61
-49
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 = "c95acde3ffa5f333efd0a7d49139b6b738935c6b", 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: 60 additions & 48 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,8 +1039,25 @@ 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.
1044-
#[cfg(any(target_os = "freebsd", target_os = "linux"))]
1055+
#[cfg(any(
1056+
target_os = "android",
1057+
target_os = "freebsd",
1058+
target_env = "gnu",
1059+
target_env = "uclibc",
1060+
))]
10451061
#[cfg_attr(docsrs, doc(cfg(all())))]
10461062
SigevThreadId {
10471063
/// Signal to send
@@ -1062,10 +1078,7 @@ mod sigevent {
10621078
#![any(feature = "aio", feature = "signal")]
10631079

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

10701083
/// Used to request asynchronous notification of the completion of certain
10711084
/// events, such as POSIX AIO and timers.
@@ -1093,53 +1106,52 @@ mod sigevent {
10931106
// See https://github.com/nix-rust/nix/issues/1441
10941107
#[cfg_attr(target_os = "fuchsia", allow(invalid_value))]
10951108
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,
1109+
let mut sev: libc::sigevent = unsafe { mem::zeroed() };
1110+
match sigev_notify {
1111+
SigevNotify::SigevNone => {
1112+
sev.sigev_notify = libc::SIGEV_NONE;
1113+
},
1114+
SigevNotify::SigevSignal{signal, si_value} => {
1115+
sev.sigev_notify = libc::SIGEV_SIGNAL;
1116+
sev.sigev_signo = signal as libc::c_int;
1117+
sev.sigev_value.sival_ptr = si_value as *mut libc::c_void
1118+
},
11001119
#[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
1101-
SigevNotify::SigevKevent{..} => libc::SIGEV_KEVENT,
1120+
SigevNotify::SigevKevent{kq, udata} => {
1121+
sev.sigev_notify = libc::SIGEV_KEVENT;
1122+
sev.sigev_signo = kq;
1123+
sev.sigev_value.sival_ptr = udata as *mut libc::c_void;
1124+
},
11021125
#[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);
1126+
#[cfg(feature = "event")]
1127+
SigevNotify::SigevKeventFlags{kq, udata, flags} => {
1128+
sev.sigev_notify = libc::SIGEV_KEVENT;
1129+
sev.sigev_signo = kq;
1130+
sev.sigev_value.sival_ptr = udata as *mut libc::c_void;
1131+
sev._sigev_un._kevent_flags = flags.bits();
1132+
},
1133+
#[cfg(target_os = "freebsd")]
1134+
SigevNotify::SigevThreadId{signal, thread_id, si_value} => {
1135+
sev.sigev_notify = libc::SIGEV_THREAD_ID;
1136+
sev.sigev_signo = signal as libc::c_int;
1137+
sev.sigev_value.sival_ptr = si_value as *mut libc::c_void;
1138+
sev._sigev_un._threadid = thread_id;
1139+
}
1140+
#[cfg(any(
1141+
target_os = "android",
1142+
target_env = "gnu",
1143+
target_env = "uclibc",
1144+
))]
1145+
SigevNotify::SigevThreadId{signal, thread_id, si_value} => {
1146+
sev.sigev_notify = libc::SIGEV_THREAD_ID;
1147+
sev.sigev_signo = signal as libc::c_int;
1148+
sev.sigev_value.sival_ptr = si_value as *mut libc::c_void;
1149+
sev._sigev_un._tid = thread_id;
1150+
}
1151+
}
11281152
SigEvent{sigevent: sev}
11291153
}
11301154

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-
11431155
/// Return a copy of the inner structure
11441156
pub fn sigevent(&self) -> libc::sigevent {
11451157
self.sigevent

0 commit comments

Comments
 (0)