1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-23 09:57:35 +00:00

Kernel: Implement basic SIGSTOP and SIGCONT support.

This commit is contained in:
Andreas Kling 2019-02-28 12:27:26 +01:00
parent c5a32d139a
commit e427b514dc
3 changed files with 19 additions and 4 deletions

View file

@ -810,10 +810,23 @@ ShouldUnblockProcess Process::dispatch_signal(byte signal)
// Mark this signal as handled.
m_pending_signals &= ~(1 << signal);
if (signal == SIGSTOP) {
set_state(Stopped);
return ShouldUnblockProcess::No;
}
if (signal == SIGCONT && state() == Stopped) {
set_state(Runnable);
return ShouldUnblockProcess::Yes;
}
auto handler_laddr = action.handler_or_sigaction;
if (handler_laddr.is_null()) {
if (signal == SIGSTOP) {
set_state(Stopped);
} else {
// FIXME: Is termination really always the appropriate action?
terminate_due_to_signal(signal);
}
return ShouldUnblockProcess::No;
}

View file

@ -65,6 +65,7 @@ public:
Skip0SchedulerPasses,
Dying,
Dead,
Stopped,
BeingInspected,
BlockedLurking,
BlockedSleep,
@ -89,7 +90,7 @@ public:
bool is_ring0() const { return m_ring == Ring0; }
bool is_ring3() const { return m_ring == Ring3; }
bool is_stopped() const { return m_state == Stopped; }
bool is_blocked() const
{
return m_state == BlockedSleep || m_state == BlockedWait || m_state == BlockedRead || m_state == BlockedWrite || m_state == BlockedSignal || m_state == BlockedSelect;
@ -444,6 +445,7 @@ static inline const char* to_string(Process::State state)
case Process::Running: return "Running";
case Process::Dying: return "Dying";
case Process::Dead: return "Dead";
case Process::Stopped: return "Stopped";
case Process::Skip1SchedulerPass: return "Skip1";
case Process::Skip0SchedulerPasses: return "Skip0";
case Process::BlockedSleep: return "Sleep";

View file

@ -168,7 +168,7 @@ bool Scheduler::pick_next()
// FIXME: Maybe we could check when returning from a syscall if there's a pending
// signal and dispatch it then and there? Would that be doable without the
// syscall effectively being "interrupted" despite having completed?
if (process.in_kernel() && !process.is_blocked())
if (process.in_kernel() && !process.is_blocked() && !process.is_stopped())
return true;
// NOTE: dispatch_one_pending_signal() may unblock the process.
bool was_blocked = process.is_blocked();