mirror of
https://github.com/RGBCube/serenity
synced 2025-07-23 10:37:41 +00:00
Kernel: Implement basic SIGSTOP and SIGCONT support.
This commit is contained in:
parent
c5a32d139a
commit
e427b514dc
3 changed files with 19 additions and 4 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue