Implement sigsuspend.
This commit is contained in:
+23
-4
@@ -657,11 +657,30 @@ pub unsafe fn sigaltstack(
|
||||
|
||||
pub const MIN_SIGALTSTACK_SIZE: usize = 8192;
|
||||
|
||||
pub fn currently_pending() -> u64 {
|
||||
pub fn currently_pending_blocked() -> u64 {
|
||||
let control = &unsafe { Tcb::current().unwrap() }.os_specific.control;
|
||||
let w0 = control.word[0].load(Ordering::Relaxed);
|
||||
let w1 = control.word[1].load(Ordering::Relaxed);
|
||||
let pending_blocked_lo = w0 & !(w0 >> 32);
|
||||
let pending_unblocked_hi = w1 & !(w0 >> 32);
|
||||
pending_blocked_lo | (pending_unblocked_hi << 32)
|
||||
let allow = (w0 >> 32) | ((w1 >> 32) << 32);
|
||||
let thread_pending = (w0 & 0xffff_ffff) | ((w1 >> 32) & 0xffff_ffff);
|
||||
let proc_pending = PROC_CONTROL_STRUCT.pending.load(Ordering::Relaxed);
|
||||
|
||||
core::sync::atomic::fence(Ordering::Acquire); // TODO: Correct ordering?
|
||||
|
||||
(thread_pending | proc_pending) & !allow
|
||||
}
|
||||
pub enum Unreachable {}
|
||||
pub fn wait_with_mask(mask: u64) -> Result<Unreachable, Error> {
|
||||
let mut old = 0;
|
||||
set_sigmask(Some(mask), Some(&mut old))?;
|
||||
let res = syscall::nanosleep(
|
||||
&syscall::TimeSpec {
|
||||
tv_sec: i64::MAX,
|
||||
tv_nsec: 0,
|
||||
},
|
||||
&mut syscall::TimeSpec::default(),
|
||||
);
|
||||
set_sigmask(Some(old), None)?;
|
||||
res?;
|
||||
unreachable!()
|
||||
}
|
||||
|
||||
@@ -359,7 +359,7 @@ pub unsafe extern "C" fn sigset(
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn sigsuspend(sigmask: *const sigset_t) -> c_int {
|
||||
Sys::sigsuspend(&*sigmask)
|
||||
Err(Sys::sigsuspend(&*sigmask)).or_minus_one_errno()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
|
||||
@@ -155,8 +155,10 @@ impl PalSignal for Sys {
|
||||
.map(|_| ())
|
||||
}
|
||||
|
||||
fn sigsuspend(set: &sigset_t) -> c_int {
|
||||
unsafe { e(syscall!(RT_SIGSUSPEND, set as *const sigset_t, NSIG / 8)) as c_int }
|
||||
fn sigsuspend(set: &sigset_t) -> Errno {
|
||||
unsafe {
|
||||
e_raw(syscall!(RT_SIGSUSPEND, set as *const sigset_t, NSIG / 8)).expect_err("must fail")
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn sigtimedwait(
|
||||
|
||||
@@ -37,7 +37,7 @@ pub trait PalSignal: Pal {
|
||||
oset: Option<&mut sigset_t>,
|
||||
) -> Result<(), Errno>;
|
||||
|
||||
fn sigsuspend(set: &sigset_t) -> c_int;
|
||||
fn sigsuspend(set: &sigset_t) -> Errno; // always fails
|
||||
|
||||
unsafe fn sigtimedwait(set: *const sigset_t, sig: *mut siginfo_t, tp: *const timespec)
|
||||
-> c_int;
|
||||
|
||||
@@ -246,7 +246,7 @@ impl PalSignal for Sys {
|
||||
}
|
||||
|
||||
fn sigpending(set: &mut sigset_t) -> Result<(), Errno> {
|
||||
*set = redox_rt::signal::currently_pending();
|
||||
*set = redox_rt::signal::currently_pending_blocked();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -264,20 +264,11 @@ impl PalSignal for Sys {
|
||||
})
|
||||
}
|
||||
|
||||
fn sigsuspend(set: &sigset_t) -> c_int {
|
||||
//TODO: correct implementation
|
||||
let mut oset = sigset_t::default();
|
||||
if let Err(err) = redox_rt::signal::set_sigmask(Some(*set), Some(&mut oset)) {
|
||||
Errno::from(err).sync();
|
||||
return -1;
|
||||
fn sigsuspend(set: &sigset_t) -> Errno {
|
||||
match redox_rt::signal::wait_with_mask(*set) {
|
||||
Ok(_) => unreachable!(),
|
||||
Err(err) => err.into(),
|
||||
}
|
||||
//TODO: wait for signal
|
||||
Self::sched_yield();
|
||||
if let Err(err) = redox_rt::signal::set_sigmask(Some(oset), None) {
|
||||
Errno::from(err).sync();
|
||||
return -1;
|
||||
}
|
||||
0
|
||||
}
|
||||
|
||||
unsafe fn sigtimedwait(
|
||||
|
||||
Reference in New Issue
Block a user