Don't unblock a blocked process when it ignores a signal.

This commit is contained in:
Andreas Kling 2018-11-16 21:14:25 +01:00
parent a788e85c09
commit 6cedb88153
Notes: sideshowbarker 2024-07-19 16:10:08 +09:00
3 changed files with 13 additions and 11 deletions

View file

@ -745,7 +745,7 @@ bool Process::has_unmasked_pending_signals() const
return m_pending_signals & m_signal_mask;
}
void Process::dispatch_one_pending_signal()
bool Process::dispatch_one_pending_signal()
{
ASSERT_INTERRUPTS_DISABLED();
dword signal_candidates = m_pending_signals & m_signal_mask;
@ -757,10 +757,10 @@ void Process::dispatch_one_pending_signal()
break;
}
}
dispatch_signal(signal);
return dispatch_signal(signal);
}
void Process::dispatch_signal(byte signal)
bool Process::dispatch_signal(byte signal)
{
ASSERT_INTERRUPTS_DISABLED();
ASSERT(signal < 32);
@ -774,12 +774,14 @@ void Process::dispatch_signal(byte signal)
auto handler_laddr = action.handler_or_sigaction;
if (handler_laddr.is_null()) {
// FIXME: Is termination really always the appropriate action?
return terminate_due_to_signal(signal);
terminate_due_to_signal(signal);
return true;
}
m_pending_signals &= ~(1 << signal);
if (handler_laddr.asPtr() == SIG_IGN) {
dbgprintf("%s(%u) ignored signal %u\n", name().characters(), pid(), signal);
return;
dbgprintf("%s(%u) ignored signal %u\n", name().characters(), pid(), signal); return false;
}
Scheduler::prepare_to_modify_tss(*this);
@ -871,14 +873,13 @@ void Process::dispatch_signal(byte signal)
else
push_value_on_stack(m_return_to_ring3_from_signal_trampoline.get());
m_pending_signals &= ~(1 << signal);
// FIXME: This state is such a hack. It avoids trouble if 'current' is the process receiving a signal.
set_state(Skip1SchedulerPass);
#ifdef SIGNAL_DEBUG
dbgprintf("signal: Okay, %s(%u) {%s} has been primed with signal handler %w:%x\n", name().characters(), pid(), toString(state()), m_tss.cs, m_tss.eip);
#endif
return true;
}
void Process::sys$sigreturn()

View file

@ -208,8 +208,8 @@ public:
size_t max_open_file_descriptors() const { return m_max_open_file_descriptors; }
void send_signal(byte signal, Process* sender);
void dispatch_one_pending_signal();
void dispatch_signal(byte signal);
bool dispatch_one_pending_signal();
bool dispatch_signal(byte signal);
bool has_unmasked_pending_signals() const;
void terminate_due_to_signal(byte signal);

View file

@ -96,7 +96,8 @@ bool Scheduler::pick_next()
// syscall effectively being "interrupted" despite having completed?
if (process.in_kernel() && !process.is_blocked())
return true;
process.dispatch_one_pending_signal();
if (!process.dispatch_one_pending_signal())
return true;
if (process.is_blocked()) {
process.m_was_interrupted_while_blocked = true;
process.unblock();