mirror of
https://github.com/hexagonal-sun/moss-kernel.git
synced 2026-01-31 09:31:58 -05:00
kill: awake sleepy tasks on SIGKILL
If a SIGKILL has been received, ensure all sleepy tasks are set to runnable so that they can action the signal.
This commit is contained in:
committed by
Ashwin Naren
parent
df578992b8
commit
abbc8261c5
@@ -1,5 +1,5 @@
|
||||
use super::{Task, Tid};
|
||||
use crate::{memory::uaccess::UserCopyable, sync::SpinLock};
|
||||
use super::{Task, TaskState, Tid};
|
||||
use crate::{memory::uaccess::UserCopyable, sched::waker::create_waker, sync::SpinLock};
|
||||
use alloc::{
|
||||
collections::btree_map::BTreeMap,
|
||||
sync::{Arc, Weak},
|
||||
@@ -12,7 +12,7 @@ use core::{
|
||||
};
|
||||
use pid::PidT;
|
||||
use rsrc_lim::ResourceLimits;
|
||||
use signal::{SigSet, SignalActionState};
|
||||
use signal::{SigId, SigSet, SignalActionState};
|
||||
use wait::ChildNotifiers;
|
||||
|
||||
pub mod builder;
|
||||
@@ -155,6 +155,30 @@ impl ThreadGroup {
|
||||
pub fn get(id: Tgid) -> Option<Arc<Self>> {
|
||||
TG_LIST.lock_save_irq().get(&id).and_then(|x| x.upgrade())
|
||||
}
|
||||
|
||||
pub fn deliver_signal(&self, signal: SigId) {
|
||||
match signal {
|
||||
SigId::SIGKILL => {
|
||||
// Set the sigkill marker in the pending signals and wake up all
|
||||
// tasks in this group.
|
||||
*self.pending_signals.lock_save_irq() = SigSet::SIGKILL;
|
||||
|
||||
for task in self.tasks.lock_save_irq().values() {
|
||||
if let Some(task) = task.upgrade()
|
||||
&& matches!(
|
||||
*task.state.lock_save_irq(),
|
||||
TaskState::Stopped | TaskState::Sleeping
|
||||
)
|
||||
{
|
||||
create_waker(task.descriptor()).wake();
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
self.pending_signals.lock_save_irq().set_signal(signal);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for ThreadGroup {
|
||||
|
||||
@@ -16,18 +16,15 @@ pub fn sys_kill(pid: PidT, signal: UserSigId) -> Result<usize> {
|
||||
let current_task = current_task();
|
||||
// Kill ourselves
|
||||
if pid == current_task.process.tgid.value() as PidT {
|
||||
current_task
|
||||
.process
|
||||
.pending_signals
|
||||
.lock_save_irq()
|
||||
.set_signal(signal);
|
||||
current_task.process.deliver_signal(signal);
|
||||
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
match pid {
|
||||
p if p > 0 => {
|
||||
let target_tg = ThreadGroup::get(Tgid(p as _)).ok_or(KernelError::NoProcess)?;
|
||||
target_tg.pending_signals.lock_save_irq().set_signal(signal);
|
||||
target_tg.deliver_signal(signal);
|
||||
}
|
||||
|
||||
0 => {
|
||||
@@ -41,7 +38,7 @@ pub fn sys_kill(pid: PidT, signal: UserSigId) -> Result<usize> {
|
||||
if let Some(tg) = tg_weak.upgrade()
|
||||
&& *tg.pgid.lock_save_irq() == our_pgid
|
||||
{
|
||||
tg.pending_signals.lock_save_irq().set_signal(signal);
|
||||
tg.deliver_signal(signal);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -55,7 +52,7 @@ pub fn sys_kill(pid: PidT, signal: UserSigId) -> Result<usize> {
|
||||
if let Some(tg) = tg_weak.upgrade()
|
||||
&& *tg.pgid.lock_save_irq() == target_pgid
|
||||
{
|
||||
tg.pending_signals.lock_save_irq().set_signal(signal);
|
||||
tg.deliver_signal(signal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -274,10 +274,7 @@ pub fn dispatch_userspace_task(ctx: *mut UserCtx) {
|
||||
.child_notifiers
|
||||
.child_update(process.tgid, ChildState::Stop { signal });
|
||||
|
||||
parent
|
||||
.pending_signals
|
||||
.lock_save_irq()
|
||||
.set_signal(SigId::SIGCHLD);
|
||||
parent.deliver_signal(SigId::SIGCHLD);
|
||||
}
|
||||
|
||||
for thr_weak in process.tasks.lock_save_irq().values() {
|
||||
@@ -313,10 +310,8 @@ pub fn dispatch_userspace_task(ctx: *mut UserCtx) {
|
||||
parent
|
||||
.child_notifiers
|
||||
.child_update(process.tgid, ChildState::Continue);
|
||||
parent
|
||||
.pending_signals
|
||||
.lock_save_irq()
|
||||
.set_signal(SigId::SIGCHLD);
|
||||
|
||||
parent.deliver_signal(SigId::SIGCHLD);
|
||||
}
|
||||
|
||||
// Re-process kernel work for this task (there may be more to do).
|
||||
|
||||
@@ -26,7 +26,7 @@ unsafe fn wake_waker(data: *const ()) {
|
||||
|
||||
match *state {
|
||||
// If the task has been put to sleep, then wake it up.
|
||||
TaskState::Sleeping => {
|
||||
TaskState::Sleeping | TaskState::Stopped => {
|
||||
if locus == CpuId::this() {
|
||||
*state = TaskState::Runnable;
|
||||
SCHED_STATE.borrow_mut().wakeup(desc);
|
||||
|
||||
Reference in New Issue
Block a user