Skip to content

Commit 262d5d9

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 6fb3a8f commit 262d5d9

File tree

2 files changed

+63
-50
lines changed

2 files changed

+63
-50
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.147", features = ["extra_traits"] }
30+
libc = { git = "https://github.com/asomers/libc.git", rev = "d81b318adeae923142c0b5640417cd90509e02ca", features = [ "extra_traits" ] }
3131
bitflags = "2.3.1"
3232
cfg-if = "1.0"
3333
pin-utils = { version = "0.1.0", optional = true }

src/sys/signal.rs

Lines changed: 62 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1022,7 +1022,7 @@ feature! {
10221022
#[cfg(target_os = "freebsd")]
10231023
pub type type_of_thread_id = libc::lwpid_t;
10241024
/// Identifies a thread for [`SigevNotify::SigevThreadId`]
1025-
#[cfg(target_os = "linux")]
1025+
#[cfg(any(target_env = "gnu", target_env = "uclibc"))]
10261026
pub type type_of_thread_id = libc::pid_t;
10271027

10281028
/// Specifies the notification method used by a [`SigEvent`]
@@ -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

Comments
 (0)