From 35aa24800b132e2671c37ac8043f2b05954ee5f9 Mon Sep 17 00:00:00 2001 From: 4lDO2 <4lDO2@protonmail.com> Date: Sun, 23 Jun 2024 14:28:36 +0200 Subject: [PATCH] Implement correct context sig unblocking behavior. --- src/context/context.rs | 1 + src/syscall/process.rs | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/context/context.rs b/src/context/context.rs index 5a8edb3ed4..2323130a11 100644 --- a/src/context/context.rs +++ b/src/context/context.rs @@ -286,6 +286,7 @@ impl Context { /// Unblock context, and return true if it was blocked before being marked runnable pub fn unblock(&mut self) -> bool { if self.unblock_no_ipi() { + // TODO: Only send IPI if currently running? if let Some(cpu_id) = self.cpu_id { if cpu_id != crate::cpu_id() { // Send IPI if not on current CPU diff --git a/src/syscall/process.rs b/src/syscall/process.rs index 883c788c89..e797ddf7d0 100644 --- a/src/syscall/process.rs +++ b/src/syscall/process.rs @@ -166,7 +166,7 @@ pub fn kill(pid: ContextId, sig: usize) -> Result { // Convert stopped processes to blocked if sending SIGCONT, regardless of whether // SIGCONT is blocked or ignored. It can however be controlled whether the process // will additionally ignore, defer, or handle that signal. - context.status = context::Status::Blocked; + context.status = context::Status::Runnable; if let Some((ctl, _, st)) = context.sigcontrol() { ctl.word[0].fetch_and(!(sig_bit(SIGTTIN) | sig_bit(SIGTTOU) | sig_bit(SIGTSTP)), Ordering::Relaxed); @@ -182,10 +182,12 @@ pub fn kill(pid: ContextId, sig: usize) -> Result { } } else if sig == SIGKILL { context.being_sigkilled = true; + context.unblock(); } else if let Some((ctl, _, st)) = context.sigcontrol() { let _was_new = ctl.word[sig_group].fetch_or(sig_bit(sig), Ordering::Relaxed); if (ctl.word[sig_group].load(Ordering::Relaxed) >> 32) & sig_bit(sig) == 0 { st.is_pending = true; + context.unblock(); } } else { // Discard signals if sighandler is unset. This includes both special contexts such