-
Notifications
You must be signed in to change notification settings - Fork 654
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add sigsuspend #2279
Add sigsuspend #2279
Changes from 18 commits
79e5e94
955d4ef
b2936c7
bc724a7
aaaec15
bc7b717
aed44de
2d9631d
599aa53
c174bd2
d5374fa
80f3d01
10c1db7
9e17085
9f52f57
f63e656
67f8673
4e3b666
55c49fe
682e4e9
5a7a3fe
a02d066
a20176c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Added a new API sigsuspend. |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -582,6 +582,34 @@ impl SigSet { | |||||
}) | ||||||
} | ||||||
|
||||||
/// Wait for a signal | ||||||
/// | ||||||
/// # Return value | ||||||
/// If `sigsuspend(2)` is interrupted (EINTR), this function returns `Ok`. | ||||||
/// If `sigsuspend(2)` set other error, this function returns `Err`. | ||||||
/// | ||||||
/// For more information see the | ||||||
/// [`sigsuspend(2)`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/sigsuspend.html). | ||||||
#[cfg(any( | ||||||
target_os = "linux", | ||||||
target_os = "android", | ||||||
target_os = "hurd", | ||||||
target_os = "nto", | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please remove this as we are not sure if we should support this target There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I removed |
||||||
target_os = "aix", | ||||||
target_os = "fushsia" | ||||||
))] | ||||||
#[doc(alias("sigsuspend"))] | ||||||
pub fn suspend(&self) -> Result<()> { | ||||||
let res = unsafe { | ||||||
libc::sigsuspend(&self.sigset as *const libc::sigset_t) | ||||||
}; | ||||||
match Errno::result(res).map(drop) { | ||||||
Err(Errno::EINTR) => Ok(()), | ||||||
Err(e) => Err(e), | ||||||
Ok(_) => unreachable!(), | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It might be better to slightly state why the
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I added reason. |
||||||
} | ||||||
} | ||||||
|
||||||
/// Converts a `libc::sigset_t` object to a [`SigSet`] without checking whether the | ||||||
/// `libc::sigset_t` is already initialized. | ||||||
/// | ||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -343,6 +343,56 @@ fn test_sigwait() { | |
.unwrap(); | ||
} | ||
|
||
#[cfg(any( | ||
target_os = "linux", | ||
target_os = "android", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same here, use alias please. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I fixed it. |
||
target_os = "hurd", | ||
target_os = "nto", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please remove this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I removed |
||
target_os = "aix", | ||
target_os = "fushsia" | ||
))] | ||
#[test] | ||
fn test_sigsuspend() { | ||
// This test change signal handler | ||
let _m = crate::SIGNAL_MTX.lock(); | ||
static SIGNAL_RECIEVED: AtomicBool = AtomicBool::new(false); | ||
extern "C" fn test_sigsuspend_handler(_: libc::c_int) { | ||
assert!(!SIGNAL_RECIEVED.swap(true, Ordering::SeqCst)); | ||
} | ||
thread::spawn(|| { | ||
const SIGNAL: Signal = Signal::SIGUSR1; | ||
|
||
// Add signal mask to this thread | ||
let mut signal_set = SigSet::empty(); | ||
signal_set.add(SIGNAL); | ||
signal_set.thread_block().unwrap(); | ||
|
||
// Set signal handler and save old one. | ||
let act = SigAction::new( | ||
SigHandler::Handler(test_sigsuspend_handler), | ||
SaFlags::empty(), | ||
SigSet::empty(), | ||
); | ||
let old_act = unsafe { sigaction(SIGNAL, &act) } | ||
.expect("expect to be able to set new action and get old action"); | ||
|
||
raise(SIGNAL).expect("expect be able to send signal"); | ||
// Now `SIGNAL` was sended but it is blocked. | ||
let mut not_wait_set = SigSet::all(); | ||
not_wait_set.remove(SIGNAL); | ||
// signal handler must run in SigSet::suspend() | ||
assert!(!SIGNAL_RECIEVED.load(Ordering::SeqCst)); | ||
not_wait_set.suspend().unwrap(); | ||
assert!(SIGNAL_RECIEVED.load(Ordering::SeqCst)); | ||
|
||
// Restore the signal handler. | ||
unsafe { sigaction(SIGNAL, &old_act) } | ||
.expect("expect to be able to restore old action "); | ||
}) | ||
.join() | ||
.unwrap(); | ||
} | ||
|
||
#[test] | ||
fn test_from_sigset_t_unchecked() { | ||
let src_set = SigSet::empty(); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We prefer to use alias if available:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I fixed it.