From 79e5e9460f11a0c88218be640571a222df745402 Mon Sep 17 00:00:00 2001 From: Toru3 Date: Tue, 2 Jan 2024 16:19:46 +0900 Subject: [PATCH 01/23] add sigsuspend --- src/sys/signal.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/sys/signal.rs b/src/sys/signal.rs index efa11a134b..d9d08a56d7 100644 --- a/src/sys/signal.rs +++ b/src/sys/signal.rs @@ -1003,6 +1003,18 @@ pub fn sigprocmask(how: SigmaskHow, set: Option<&SigSet>, oldset: Option<&mut Si Errno::result(res).map(drop) } +/// Wait for a signal +pub fn sigsuspend(set : &SigSet) -> Result<()> { + let res = unsafe { + libc::sigsuspend(&set.sigset as *const libc::sigset_t) + }; + match Errno::result(res).map(drop) { + Ok(_) => Ok(()), + Err(Errno::EINTR) => Ok(()), + Err(e) => Err(e), + } +} + /// Send a signal to a process /// /// # Arguments From 955d4efd84f5ddbfc36725b5f276c4d892d1eb3c Mon Sep 17 00:00:00 2001 From: Toru3 Date: Tue, 2 Jan 2024 16:40:41 +0900 Subject: [PATCH 02/23] add cfg for sigsuspend --- src/sys/signal.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/sys/signal.rs b/src/sys/signal.rs index d9d08a56d7..31cda7a0c2 100644 --- a/src/sys/signal.rs +++ b/src/sys/signal.rs @@ -1003,6 +1003,13 @@ pub fn sigprocmask(how: SigmaskHow, set: Option<&SigSet>, oldset: Option<&mut Si Errno::result(res).map(drop) } +#[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "hurd", + target_os = "nto", + target_os = "aix" +))] /// Wait for a signal pub fn sigsuspend(set : &SigSet) -> Result<()> { let res = unsafe { From b2936c777ea1b495eecd3511cbbde6cfeb075125 Mon Sep 17 00:00:00 2001 From: Toru3 Date: Tue, 2 Jan 2024 16:49:56 +0900 Subject: [PATCH 03/23] add fuchsia to target_os --- src/sys/signal.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/sys/signal.rs b/src/sys/signal.rs index 31cda7a0c2..888b07e391 100644 --- a/src/sys/signal.rs +++ b/src/sys/signal.rs @@ -1008,7 +1008,8 @@ pub fn sigprocmask(how: SigmaskHow, set: Option<&SigSet>, oldset: Option<&mut Si target_os = "android", target_os = "hurd", target_os = "nto", - target_os = "aix" + target_os = "aix", + target_os = "fushsia" ))] /// Wait for a signal pub fn sigsuspend(set : &SigSet) -> Result<()> { From bc724a7c47c0e011d400a74027b99919d0a68cb0 Mon Sep 17 00:00:00 2001 From: Toru3 Date: Tue, 2 Jan 2024 17:01:45 +0900 Subject: [PATCH 04/23] Ok is unreachable > Since sigsuspend() suspends thread execution indefinitely, there is no > successful completion return value. If a return occurs, -1 shall be > returned and errno set to indicate the error. https://pubs.opengroup.org/onlinepubs/9699919799/functions/sigsuspend.html --- src/sys/signal.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sys/signal.rs b/src/sys/signal.rs index 888b07e391..d9caca3cb5 100644 --- a/src/sys/signal.rs +++ b/src/sys/signal.rs @@ -1017,9 +1017,9 @@ pub fn sigsuspend(set : &SigSet) -> Result<()> { libc::sigsuspend(&set.sigset as *const libc::sigset_t) }; match Errno::result(res).map(drop) { - Ok(_) => Ok(()), Err(Errno::EINTR) => Ok(()), Err(e) => Err(e), + Ok(_) => unreachable!(), } } From aaaec1528f6bb3fa129828947ecf8c3802cb83fc Mon Sep 17 00:00:00 2001 From: Toru3 Date: Tue, 2 Jan 2024 23:03:15 +0900 Subject: [PATCH 05/23] add test_sigsuspend --- test/sys/test_signal.rs | 83 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 82 insertions(+), 1 deletion(-) diff --git a/test/sys/test_signal.rs b/test/sys/test_signal.rs index eb6347d5b0..15b7e96965 100644 --- a/test/sys/test_signal.rs +++ b/test/sys/test_signal.rs @@ -3,7 +3,10 @@ use nix::sys::signal::*; use nix::unistd::*; use std::convert::TryFrom; use std::hash::{Hash, Hasher}; -use std::sync::atomic::{AtomicBool, Ordering}; +use std::sync::{ + atomic::{AtomicBool, Ordering}, + Arc, +}; #[cfg(not(target_os = "redox"))] use std::thread; @@ -80,6 +83,84 @@ fn test_sigprocmask() { .expect("expect to be able to block signals"); } +static SIGSUSPEND_SIGNALED: AtomicBool = AtomicBool::new(false); + +extern "C" fn test_sigsuspend_handler(_: libc::c_int) { + assert_eq!(SIGSUSPEND_SIGNALED.swap(true, Ordering::SeqCst), false); +} + +#[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "hurd", + target_os = "nto", + target_os = "aix", + target_os = "fushsia" +))] +#[test] +fn test_sigsuspend() { + let _m = crate::SIGNAL_MTX.lock(); + + const SIGNAL: Signal = Signal::SIGUSR1; + + let mut old_signal_set = SigSet::empty(); + + // Block the signal and retrieve old signals. + let mut signal_set = SigSet::empty(); + signal_set.add(SIGNAL); + sigprocmask( + SigmaskHow::SIG_BLOCK, + Some(&SigSet::all()), + Some(&mut old_signal_set), + ) + .expect("expect to be able to block signals and get old signal masks"); + + let thread_waked = Arc::new(AtomicBool::new(false)); + let sended_signal = Arc::new(AtomicBool::new(false)); + SIGSUSPEND_SIGNALED.store(false, Ordering::SeqCst); + 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 action and get old action") + }; + + let h = { + let sended_signal = Arc::clone(&sended_signal); + let thread_waked = Arc::clone(&thread_waked); + thread::spawn(move || { + thread_waked.store(true, Ordering::SeqCst); + let mut not_wait_set = SigSet::all(); + not_wait_set.remove(SIGNAL); + while !sended_signal.load(Ordering::SeqCst) { + thread::yield_now(); + } + assert_eq!(SIGSUSPEND_SIGNALED.load(Ordering::SeqCst), false); + sigsuspend(¬_wait_set).unwrap(); + assert_eq!(SIGSUSPEND_SIGNALED.load(Ordering::SeqCst), true); + }) + }; + while !thread_waked.load(Ordering::SeqCst) { + thread::yield_now(); + } + kill(nix::unistd::Pid::this(), Some(SIGNAL)) + .expect("expect be able to send signal"); + sended_signal.store(true, Ordering::SeqCst); + + h.join().unwrap(); + + unsafe { + sigaction(SIGNAL, &old_act) + .expect("expect to be able to set action and get old action") + }; + // Reset the signal. + sigprocmask(SigmaskHow::SIG_SETMASK, Some(&old_signal_set), None) + .expect("expect to be able to set mask of signals"); +} + static SIGNALED: AtomicBool = AtomicBool::new(false); extern "C" fn test_sigaction_handler(signal: libc::c_int) { From bc7b7174633943d2cdd839e2ac04e82f86fdd30c Mon Sep 17 00:00:00 2001 From: Toru3 Date: Tue, 2 Jan 2024 23:07:14 +0900 Subject: [PATCH 06/23] clippy --- test/sys/test_signal.rs | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/test/sys/test_signal.rs b/test/sys/test_signal.rs index 15b7e96965..3580509369 100644 --- a/test/sys/test_signal.rs +++ b/test/sys/test_signal.rs @@ -3,10 +3,16 @@ use nix::sys::signal::*; use nix::unistd::*; use std::convert::TryFrom; use std::hash::{Hash, Hasher}; -use std::sync::{ - atomic::{AtomicBool, Ordering}, - Arc, -}; +use std::sync::atomic::{AtomicBool, Ordering}; +#[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "hurd", + target_os = "nto", + target_os = "aix", + target_os = "fushsia" +))] +use std::sync::Arc; #[cfg(not(target_os = "redox"))] use std::thread; @@ -83,10 +89,26 @@ fn test_sigprocmask() { .expect("expect to be able to block signals"); } +#[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "hurd", + target_os = "nto", + target_os = "aix", + target_os = "fushsia" +))] static SIGSUSPEND_SIGNALED: AtomicBool = AtomicBool::new(false); +#[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "hurd", + target_os = "nto", + target_os = "aix", + target_os = "fushsia" +))] extern "C" fn test_sigsuspend_handler(_: libc::c_int) { - assert_eq!(SIGSUSPEND_SIGNALED.swap(true, Ordering::SeqCst), false); + assert!(!SIGSUSPEND_SIGNALED.swap(true, Ordering::SeqCst)); } #[cfg(any( @@ -138,9 +160,9 @@ fn test_sigsuspend() { while !sended_signal.load(Ordering::SeqCst) { thread::yield_now(); } - assert_eq!(SIGSUSPEND_SIGNALED.load(Ordering::SeqCst), false); + assert!(!SIGSUSPEND_SIGNALED.load(Ordering::SeqCst)); sigsuspend(¬_wait_set).unwrap(); - assert_eq!(SIGSUSPEND_SIGNALED.load(Ordering::SeqCst), true); + assert!(SIGSUSPEND_SIGNALED.load(Ordering::SeqCst)); }) }; while !thread_waked.load(Ordering::SeqCst) { From aed44de34952f5bf9e7f799ec4cbd9d3d441dc2a Mon Sep 17 00:00:00 2001 From: Toru3 Date: Wed, 3 Jan 2024 11:47:36 +0900 Subject: [PATCH 07/23] fix bug of test --- test/sys/test_signal.rs | 106 ++++++++++++---------------------------- 1 file changed, 32 insertions(+), 74 deletions(-) diff --git a/test/sys/test_signal.rs b/test/sys/test_signal.rs index 3580509369..039104eeba 100644 --- a/test/sys/test_signal.rs +++ b/test/sys/test_signal.rs @@ -4,15 +4,6 @@ use nix::unistd::*; use std::convert::TryFrom; use std::hash::{Hash, Hasher}; use std::sync::atomic::{AtomicBool, Ordering}; -#[cfg(any( - target_os = "linux", - target_os = "android", - target_os = "hurd", - target_os = "nto", - target_os = "aix", - target_os = "fushsia" -))] -use std::sync::Arc; #[cfg(not(target_os = "redox"))] use std::thread; @@ -89,28 +80,6 @@ fn test_sigprocmask() { .expect("expect to be able to block signals"); } -#[cfg(any( - target_os = "linux", - target_os = "android", - target_os = "hurd", - target_os = "nto", - target_os = "aix", - target_os = "fushsia" -))] -static SIGSUSPEND_SIGNALED: AtomicBool = AtomicBool::new(false); - -#[cfg(any( - target_os = "linux", - target_os = "android", - target_os = "hurd", - target_os = "nto", - target_os = "aix", - target_os = "fushsia" -))] -extern "C" fn test_sigsuspend_handler(_: libc::c_int) { - assert!(!SIGSUSPEND_SIGNALED.swap(true, Ordering::SeqCst)); -} - #[cfg(any( target_os = "linux", target_os = "android", @@ -121,66 +90,55 @@ extern "C" fn test_sigsuspend_handler(_: libc::c_int) { ))] #[test] fn test_sigsuspend() { + static SENDED_SIGNAL: AtomicBool = AtomicBool::new(false); + static SIGNAL_RECIEVED: AtomicBool = AtomicBool::new(false); + extern "C" fn test_sigsuspend_handler(_: libc::c_int) { + assert!(!SIGNAL_RECIEVED.swap(true, Ordering::SeqCst)); + assert!(SENDED_SIGNAL.load(Ordering::SeqCst)); + } + let _m = crate::SIGNAL_MTX.lock(); const SIGNAL: Signal = Signal::SIGUSR1; - let mut old_signal_set = SigSet::empty(); + // Reset static variable (making sure) + SIGNAL_RECIEVED.store(false, Ordering::SeqCst); + SENDED_SIGNAL.store(false, Ordering::SeqCst); - // Block the signal and retrieve old signals. + // Set signal mask and handler and save old ones. + let mut old_signal_set = SigSet::empty(); let mut signal_set = SigSet::empty(); signal_set.add(SIGNAL); sigprocmask( SigmaskHow::SIG_BLOCK, - Some(&SigSet::all()), + Some(&signal_set), Some(&mut old_signal_set), ) - .expect("expect to be able to block signals and get old signal masks"); - - let thread_waked = Arc::new(AtomicBool::new(false)); - let sended_signal = Arc::new(AtomicBool::new(false)); - SIGSUSPEND_SIGNALED.store(false, Ordering::SeqCst); + .expect("expect to be able to add signal mask and get old signal masks"); 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 action and get old action") - }; - - let h = { - let sended_signal = Arc::clone(&sended_signal); - let thread_waked = Arc::clone(&thread_waked); - thread::spawn(move || { - thread_waked.store(true, Ordering::SeqCst); - let mut not_wait_set = SigSet::all(); - not_wait_set.remove(SIGNAL); - while !sended_signal.load(Ordering::SeqCst) { - thread::yield_now(); - } - assert!(!SIGSUSPEND_SIGNALED.load(Ordering::SeqCst)); - sigsuspend(¬_wait_set).unwrap(); - assert!(SIGSUSPEND_SIGNALED.load(Ordering::SeqCst)); - }) - }; - while !thread_waked.load(Ordering::SeqCst) { - thread::yield_now(); - } - kill(nix::unistd::Pid::this(), Some(SIGNAL)) - .expect("expect be able to send signal"); - sended_signal.store(true, Ordering::SeqCst); - - h.join().unwrap(); - - unsafe { - sigaction(SIGNAL, &old_act) - .expect("expect to be able to set action and get old action") - }; - // Reset the signal. + 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"); + assert!(!SENDED_SIGNAL.swap(true, Ordering::SeqCst)); + thread::sleep(std::time::Duration::from_millis(10)); + // Now `SIGNAL` was sended but it is blocked. + let mut not_wait_set = SigSet::all(); + not_wait_set.remove(SIGNAL); + assert!(!SIGNAL_RECIEVED.load(Ordering::SeqCst)); + // signal must be recived in sigsuspend + sigsuspend(¬_wait_set).unwrap(); + assert!(SIGNAL_RECIEVED.load(Ordering::SeqCst)); + + // Restore the signal mask and handler. + unsafe { sigaction(SIGNAL, &old_act) } + .expect("expect to be able to restore old action "); sigprocmask(SigmaskHow::SIG_SETMASK, Some(&old_signal_set), None) - .expect("expect to be able to set mask of signals"); + .expect("expect to be able to restore old signal mask"); } static SIGNALED: AtomicBool = AtomicBool::new(false); From 2d9631dd3e5f7f98dce9ecf51e9db5c64121b098 Mon Sep 17 00:00:00 2001 From: Toru3 Date: Wed, 3 Jan 2024 12:07:13 +0900 Subject: [PATCH 08/23] add changelog --- changelog/x.added.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog/x.added.md diff --git a/changelog/x.added.md b/changelog/x.added.md new file mode 100644 index 0000000000..5bbbbb40f7 --- /dev/null +++ b/changelog/x.added.md @@ -0,0 +1 @@ +Added a new API sigsuspend. From 599aa53cd118bf1fe7d8ebc7f9bb242688367329 Mon Sep 17 00:00:00 2001 From: Toru3 Date: Wed, 3 Jan 2024 13:05:04 +0900 Subject: [PATCH 09/23] update doc --- src/sys/signal.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/sys/signal.rs b/src/sys/signal.rs index d9caca3cb5..46f1aec806 100644 --- a/src/sys/signal.rs +++ b/src/sys/signal.rs @@ -1012,6 +1012,13 @@ pub fn sigprocmask(how: SigmaskHow, set: Option<&SigSet>, oldset: Option<&mut Si target_os = "fushsia" ))] /// 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). pub fn sigsuspend(set : &SigSet) -> Result<()> { let res = unsafe { libc::sigsuspend(&set.sigset as *const libc::sigset_t) From c174bd2fe076429226048608f80e9cdf55634a98 Mon Sep 17 00:00:00 2001 From: Toru3 Date: Wed, 3 Jan 2024 13:05:26 +0900 Subject: [PATCH 10/23] remove unnnessesary sleep --- test/sys/test_signal.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/test/sys/test_signal.rs b/test/sys/test_signal.rs index 039104eeba..686bd2f556 100644 --- a/test/sys/test_signal.rs +++ b/test/sys/test_signal.rs @@ -125,7 +125,6 @@ fn test_sigsuspend() { raise(SIGNAL).expect("expect be able to send signal"); assert!(!SENDED_SIGNAL.swap(true, Ordering::SeqCst)); - thread::sleep(std::time::Duration::from_millis(10)); // Now `SIGNAL` was sended but it is blocked. let mut not_wait_set = SigSet::all(); not_wait_set.remove(SIGNAL); From d5374fa0de1362e3059ee5d932c6df3dda36d4f3 Mon Sep 17 00:00:00 2001 From: Toru3 Date: Wed, 3 Jan 2024 13:11:44 +0900 Subject: [PATCH 11/23] Revert "remove unnnessesary sleep" This reverts commit c174bd2fe076429226048608f80e9cdf55634a98. --- test/sys/test_signal.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/test/sys/test_signal.rs b/test/sys/test_signal.rs index 686bd2f556..039104eeba 100644 --- a/test/sys/test_signal.rs +++ b/test/sys/test_signal.rs @@ -125,6 +125,7 @@ fn test_sigsuspend() { raise(SIGNAL).expect("expect be able to send signal"); assert!(!SENDED_SIGNAL.swap(true, Ordering::SeqCst)); + thread::sleep(std::time::Duration::from_millis(10)); // Now `SIGNAL` was sended but it is blocked. let mut not_wait_set = SigSet::all(); not_wait_set.remove(SIGNAL); From 80f3d014e5d32567f76e219d058b5b34ac79c720 Mon Sep 17 00:00:00 2001 From: Toru3 Date: Wed, 3 Jan 2024 13:24:07 +0900 Subject: [PATCH 12/23] move to SigSet::suspend --- src/sys/signal.rs | 56 +++++++++++++++++++++-------------------- test/sys/test_signal.rs | 2 +- 2 files changed, 30 insertions(+), 28 deletions(-) diff --git a/src/sys/signal.rs b/src/sys/signal.rs index 46f1aec806..b8c0e3603b 100644 --- a/src/sys/signal.rs +++ b/src/sys/signal.rs @@ -582,6 +582,35 @@ impl SigSet { }) } + #[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "hurd", + target_os = "nto", + target_os = "aix", + target_os = "fushsia" + ))] + #[doc(alias("sigsuspend"))] + /// 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). + 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!(), + } + } + + /// Converts a `libc::sigset_t` object to a [`SigSet`] without checking whether the /// `libc::sigset_t` is already initialized. /// @@ -1003,33 +1032,6 @@ pub fn sigprocmask(how: SigmaskHow, set: Option<&SigSet>, oldset: Option<&mut Si Errno::result(res).map(drop) } -#[cfg(any( - target_os = "linux", - target_os = "android", - target_os = "hurd", - target_os = "nto", - target_os = "aix", - target_os = "fushsia" -))] -/// 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). -pub fn sigsuspend(set : &SigSet) -> Result<()> { - let res = unsafe { - libc::sigsuspend(&set.sigset as *const libc::sigset_t) - }; - match Errno::result(res).map(drop) { - Err(Errno::EINTR) => Ok(()), - Err(e) => Err(e), - Ok(_) => unreachable!(), - } -} - /// Send a signal to a process /// /// # Arguments diff --git a/test/sys/test_signal.rs b/test/sys/test_signal.rs index 039104eeba..64c8f9e61a 100644 --- a/test/sys/test_signal.rs +++ b/test/sys/test_signal.rs @@ -131,7 +131,7 @@ fn test_sigsuspend() { not_wait_set.remove(SIGNAL); assert!(!SIGNAL_RECIEVED.load(Ordering::SeqCst)); // signal must be recived in sigsuspend - sigsuspend(¬_wait_set).unwrap(); + not_wait_set.suspend().unwrap(); assert!(SIGNAL_RECIEVED.load(Ordering::SeqCst)); // Restore the signal mask and handler. From 10c1db7b5d66b05a071aecb43e2abb1511e90493 Mon Sep 17 00:00:00 2001 From: Toru3 Date: Wed, 3 Jan 2024 13:55:42 +0900 Subject: [PATCH 13/23] reorder doc --- src/sys/signal.rs | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/sys/signal.rs b/src/sys/signal.rs index b8c0e3603b..9bba191fac 100644 --- a/src/sys/signal.rs +++ b/src/sys/signal.rs @@ -582,6 +582,14 @@ 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", @@ -591,14 +599,6 @@ impl SigSet { target_os = "fushsia" ))] #[doc(alias("sigsuspend"))] - /// 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). pub fn suspend(&self) -> Result<()> { let res = unsafe { libc::sigsuspend(&self.sigset as *const libc::sigset_t) @@ -610,7 +610,6 @@ impl SigSet { } } - /// Converts a `libc::sigset_t` object to a [`SigSet`] without checking whether the /// `libc::sigset_t` is already initialized. /// From 9e170852da5a437e80c08af63c4c24d265d7975a Mon Sep 17 00:00:00 2001 From: Toru3 Date: Wed, 3 Jan 2024 13:56:00 +0900 Subject: [PATCH 14/23] update test --- test/sys/test_signal.rs | 118 +++++++++++++++++++--------------------- 1 file changed, 57 insertions(+), 61 deletions(-) diff --git a/test/sys/test_signal.rs b/test/sys/test_signal.rs index 64c8f9e61a..9273592cb6 100644 --- a/test/sys/test_signal.rs +++ b/test/sys/test_signal.rs @@ -80,67 +80,6 @@ fn test_sigprocmask() { .expect("expect to be able to block signals"); } -#[cfg(any( - target_os = "linux", - target_os = "android", - target_os = "hurd", - target_os = "nto", - target_os = "aix", - target_os = "fushsia" -))] -#[test] -fn test_sigsuspend() { - static SENDED_SIGNAL: AtomicBool = AtomicBool::new(false); - static SIGNAL_RECIEVED: AtomicBool = AtomicBool::new(false); - extern "C" fn test_sigsuspend_handler(_: libc::c_int) { - assert!(!SIGNAL_RECIEVED.swap(true, Ordering::SeqCst)); - assert!(SENDED_SIGNAL.load(Ordering::SeqCst)); - } - - let _m = crate::SIGNAL_MTX.lock(); - - const SIGNAL: Signal = Signal::SIGUSR1; - - // Reset static variable (making sure) - SIGNAL_RECIEVED.store(false, Ordering::SeqCst); - SENDED_SIGNAL.store(false, Ordering::SeqCst); - - // Set signal mask and handler and save old ones. - let mut old_signal_set = SigSet::empty(); - let mut signal_set = SigSet::empty(); - signal_set.add(SIGNAL); - sigprocmask( - SigmaskHow::SIG_BLOCK, - Some(&signal_set), - Some(&mut old_signal_set), - ) - .expect("expect to be able to add signal mask and get old signal masks"); - 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"); - assert!(!SENDED_SIGNAL.swap(true, Ordering::SeqCst)); - thread::sleep(std::time::Duration::from_millis(10)); - // Now `SIGNAL` was sended but it is blocked. - let mut not_wait_set = SigSet::all(); - not_wait_set.remove(SIGNAL); - assert!(!SIGNAL_RECIEVED.load(Ordering::SeqCst)); - // signal must be recived in sigsuspend - not_wait_set.suspend().unwrap(); - assert!(SIGNAL_RECIEVED.load(Ordering::SeqCst)); - - // Restore the signal mask and handler. - unsafe { sigaction(SIGNAL, &old_act) } - .expect("expect to be able to restore old action "); - sigprocmask(SigmaskHow::SIG_SETMASK, Some(&old_signal_set), None) - .expect("expect to be able to restore old signal mask"); -} - static SIGNALED: AtomicBool = AtomicBool::new(false); extern "C" fn test_sigaction_handler(signal: libc::c_int) { @@ -404,6 +343,63 @@ fn test_sigwait() { .unwrap(); } +#[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "hurd", + target_os = "nto", + target_os = "aix", + target_os = "fushsia" +))] +#[test] +fn test_sigsuspend() { + // This test change signal handler + let _m = crate::SIGNAL_MTX.lock(); + static SENDED_SIGNAL: AtomicBool = AtomicBool::new(false); + static SIGNAL_RECIEVED: AtomicBool = AtomicBool::new(false); + extern "C" fn test_sigsuspend_handler(_: libc::c_int) { + assert!(!SIGNAL_RECIEVED.swap(true, Ordering::SeqCst)); + assert!(SENDED_SIGNAL.load(Ordering::SeqCst)); + } + thread::spawn(|| { + const SIGNAL: Signal = Signal::SIGUSR1; + + // Reset static variable (making sure) + SIGNAL_RECIEVED.store(false, Ordering::SeqCst); + SENDED_SIGNAL.store(false, Ordering::SeqCst); + + // Set 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"); + assert!(!SENDED_SIGNAL.swap(true, Ordering::SeqCst)); + // 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(); From 9f52f5746e3cb13b3156914a415082dec3072ed9 Mon Sep 17 00:00:00 2001 From: Toru3 Date: Wed, 3 Jan 2024 14:02:46 +0900 Subject: [PATCH 15/23] update test --- test/sys/test_signal.rs | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/test/sys/test_signal.rs b/test/sys/test_signal.rs index 9273592cb6..4e1c4950bc 100644 --- a/test/sys/test_signal.rs +++ b/test/sys/test_signal.rs @@ -355,20 +355,14 @@ fn test_sigwait() { fn test_sigsuspend() { // This test change signal handler let _m = crate::SIGNAL_MTX.lock(); - static SENDED_SIGNAL: AtomicBool = AtomicBool::new(false); static SIGNAL_RECIEVED: AtomicBool = AtomicBool::new(false); extern "C" fn test_sigsuspend_handler(_: libc::c_int) { assert!(!SIGNAL_RECIEVED.swap(true, Ordering::SeqCst)); - assert!(SENDED_SIGNAL.load(Ordering::SeqCst)); } thread::spawn(|| { const SIGNAL: Signal = Signal::SIGUSR1; - // Reset static variable (making sure) - SIGNAL_RECIEVED.store(false, Ordering::SeqCst); - SENDED_SIGNAL.store(false, Ordering::SeqCst); - - // Set signal mask to this thread + // Add signal mask to this thread let mut signal_set = SigSet::empty(); signal_set.add(SIGNAL); signal_set.thread_block().unwrap(); @@ -383,7 +377,6 @@ fn test_sigsuspend() { .expect("expect to be able to set new action and get old action"); raise(SIGNAL).expect("expect be able to send signal"); - assert!(!SENDED_SIGNAL.swap(true, Ordering::SeqCst)); // Now `SIGNAL` was sended but it is blocked. let mut not_wait_set = SigSet::all(); not_wait_set.remove(SIGNAL); From f63e65643d4627492bfa5cb83ba4d3ed3698f31c Mon Sep 17 00:00:00 2001 From: Toru3 Date: Wed, 3 Jan 2024 14:09:32 +0900 Subject: [PATCH 16/23] change memory order --- test/sys/test_signal.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/sys/test_signal.rs b/test/sys/test_signal.rs index 4e1c4950bc..f55231f61b 100644 --- a/test/sys/test_signal.rs +++ b/test/sys/test_signal.rs @@ -357,7 +357,7 @@ fn test_sigsuspend() { 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)); + assert!(!SIGNAL_RECIEVED.swap(true, Ordering::AcqRel)); } thread::spawn(|| { const SIGNAL: Signal = Signal::SIGUSR1; @@ -381,9 +381,9 @@ fn test_sigsuspend() { 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)); + assert!(!SIGNAL_RECIEVED.load(Ordering::Acquire)); not_wait_set.suspend().unwrap(); - assert!(SIGNAL_RECIEVED.load(Ordering::SeqCst)); + assert!(SIGNAL_RECIEVED.load(Ordering::Acquire)); // Restore the signal handler. unsafe { sigaction(SIGNAL, &old_act) } From 67f8673d21ce67efc86093ee395a1b3b5f92477b Mon Sep 17 00:00:00 2001 From: Toru3 Date: Wed, 3 Jan 2024 14:15:51 +0900 Subject: [PATCH 17/23] Revert "change memory order" This reverts commit f63e65643d4627492bfa5cb83ba4d3ed3698f31c. --- test/sys/test_signal.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/sys/test_signal.rs b/test/sys/test_signal.rs index f55231f61b..4e1c4950bc 100644 --- a/test/sys/test_signal.rs +++ b/test/sys/test_signal.rs @@ -357,7 +357,7 @@ fn test_sigsuspend() { 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::AcqRel)); + assert!(!SIGNAL_RECIEVED.swap(true, Ordering::SeqCst)); } thread::spawn(|| { const SIGNAL: Signal = Signal::SIGUSR1; @@ -381,9 +381,9 @@ fn test_sigsuspend() { let mut not_wait_set = SigSet::all(); not_wait_set.remove(SIGNAL); // signal handler must run in SigSet::suspend() - assert!(!SIGNAL_RECIEVED.load(Ordering::Acquire)); + assert!(!SIGNAL_RECIEVED.load(Ordering::SeqCst)); not_wait_set.suspend().unwrap(); - assert!(SIGNAL_RECIEVED.load(Ordering::Acquire)); + assert!(SIGNAL_RECIEVED.load(Ordering::SeqCst)); // Restore the signal handler. unsafe { sigaction(SIGNAL, &old_act) } From 4e3b66681cf21b69443c86273c5b6c9ab617e372 Mon Sep 17 00:00:00 2001 From: Toru3 Date: Wed, 3 Jan 2024 14:31:07 +0900 Subject: [PATCH 18/23] rename added.md --- changelog/x.added.md => 2279.added.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename changelog/x.added.md => 2279.added.md (100%) diff --git a/changelog/x.added.md b/2279.added.md similarity index 100% rename from changelog/x.added.md rename to 2279.added.md From 55c49fe4587ef124200e5111241e6c9c28f1bff5 Mon Sep 17 00:00:00 2001 From: Toru3 Date: Sat, 6 Jan 2024 17:07:48 +0900 Subject: [PATCH 19/23] add unreachable reason --- src/sys/signal.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sys/signal.rs b/src/sys/signal.rs index 9bba191fac..0a8467a534 100644 --- a/src/sys/signal.rs +++ b/src/sys/signal.rs @@ -606,7 +606,7 @@ impl SigSet { match Errno::result(res).map(drop) { Err(Errno::EINTR) => Ok(()), Err(e) => Err(e), - Ok(_) => unreachable!(), + Ok(_) => unreachable!("because this syscall always returns -1 if returns"), } } From 682e4e9ac316aab964e4824781225aa3a4843b78 Mon Sep 17 00:00:00 2001 From: Toru3 Date: Sat, 6 Jan 2024 17:10:10 +0900 Subject: [PATCH 20/23] use alias --- src/sys/signal.rs | 3 +-- test/sys/test_signal.rs | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/sys/signal.rs b/src/sys/signal.rs index 0a8467a534..c0c2f9281d 100644 --- a/src/sys/signal.rs +++ b/src/sys/signal.rs @@ -591,8 +591,7 @@ impl SigSet { /// For more information see the /// [`sigsuspend(2)`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/sigsuspend.html). #[cfg(any( - target_os = "linux", - target_os = "android", + linux_android, target_os = "hurd", target_os = "nto", target_os = "aix", diff --git a/test/sys/test_signal.rs b/test/sys/test_signal.rs index 4e1c4950bc..32de470433 100644 --- a/test/sys/test_signal.rs +++ b/test/sys/test_signal.rs @@ -344,8 +344,7 @@ fn test_sigwait() { } #[cfg(any( - target_os = "linux", - target_os = "android", + linux_android, target_os = "hurd", target_os = "nto", target_os = "aix", From 5a7a3fec1bc8a31a3ab3e65826b58f6a318e9c74 Mon Sep 17 00:00:00 2001 From: Toru3 Date: Sat, 6 Jan 2024 17:10:49 +0900 Subject: [PATCH 21/23] remove nto --- src/sys/signal.rs | 1 - test/sys/test_signal.rs | 1 - 2 files changed, 2 deletions(-) diff --git a/src/sys/signal.rs b/src/sys/signal.rs index c0c2f9281d..808029b74e 100644 --- a/src/sys/signal.rs +++ b/src/sys/signal.rs @@ -593,7 +593,6 @@ impl SigSet { #[cfg(any( linux_android, target_os = "hurd", - target_os = "nto", target_os = "aix", target_os = "fushsia" ))] diff --git a/test/sys/test_signal.rs b/test/sys/test_signal.rs index 32de470433..eca2605e0b 100644 --- a/test/sys/test_signal.rs +++ b/test/sys/test_signal.rs @@ -346,7 +346,6 @@ fn test_sigwait() { #[cfg(any( linux_android, target_os = "hurd", - target_os = "nto", target_os = "aix", target_os = "fushsia" ))] From a02d066c35294ceef64f1f4eb427d95e88c2712a Mon Sep 17 00:00:00 2001 From: Toru3 Date: Sun, 7 Jan 2024 12:12:25 +0900 Subject: [PATCH 22/23] Update libc I updated libc to use below commit which add sigsuspend to more targets. https://github.com/rust-lang/libc/commit/11f7c7b89d9bfe8c53dcca7571c4965fa3375aab --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index f064e20f1c..202c57b52a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,7 +28,7 @@ targets = [ ] [dependencies] -libc = { git = "https://github.com/rust-lang/libc", rev = "cb18b837963c37a8d21732f3ca2c2096f04e6830", features = ["extra_traits"] } +libc = { git = "https://github.com/rust-lang/libc", rev = "2f93bfb7678e18a9fc5373dec49384bd23f601c3", features = ["extra_traits"] } bitflags = "2.3.1" cfg-if = "1.0" pin-utils = { version = "0.1.0", optional = true } From a20176ca09bac32d41d8f03c4c668c36f399029d Mon Sep 17 00:00:00 2001 From: Toru3 Date: Sun, 7 Jan 2024 12:20:30 +0900 Subject: [PATCH 23/23] Add target bsd, solarish and haiku to sigsuspend --- src/sys/signal.rs | 3 +++ test/sys/test_signal.rs | 3 +++ 2 files changed, 6 insertions(+) diff --git a/src/sys/signal.rs b/src/sys/signal.rs index 808029b74e..c9b593d0db 100644 --- a/src/sys/signal.rs +++ b/src/sys/signal.rs @@ -591,7 +591,10 @@ impl SigSet { /// For more information see the /// [`sigsuspend(2)`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/sigsuspend.html). #[cfg(any( + bsd, linux_android, + solarish, + target_os = "haiku", target_os = "hurd", target_os = "aix", target_os = "fushsia" diff --git a/test/sys/test_signal.rs b/test/sys/test_signal.rs index eca2605e0b..12872f1228 100644 --- a/test/sys/test_signal.rs +++ b/test/sys/test_signal.rs @@ -344,7 +344,10 @@ fn test_sigwait() { } #[cfg(any( + bsd, linux_android, + solarish, + target_os = "haiku", target_os = "hurd", target_os = "aix", target_os = "fushsia"