Skip to content

Commit

Permalink
Kernel: Restore the previous thread state on SIGCONT after SIGSTOP
Browse files Browse the repository at this point in the history
When stopping a thread with the SIGSTOP signal, we now store the thread
state in Thread::m_stop_state. That state is then restored on SIGCONT.
This fixes an issue where previously-blocked threads would unblock
upon resume. Now they simply resume in the Blocked state, and it's up
to the regular unblocking mechanism to unblock them.

Fixes SerenityOS#1326.
  • Loading branch information
awesomekling committed Mar 1, 2020
1 parent fbe9aad commit 2839bb0
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 4 deletions.
14 changes: 10 additions & 4 deletions Kernel/Thread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -495,13 +495,19 @@ ShouldUnblockThread Thread::dispatch_signal(u8 signal)
m_pending_signals &= ~(1 << (signal - 1));

if (signal == SIGSTOP) {
m_stop_signal = SIGSTOP;
set_state(Stopped);
if (!is_stopped()) {
m_stop_signal = SIGSTOP;
m_stop_state = m_state;
set_state(State::Stopped);
}
return ShouldUnblockThread::No;
}

if (signal == SIGCONT && state() == Stopped)
set_state(Runnable);
if (signal == SIGCONT && is_stopped()) {
ASSERT(m_stop_state != State::Invalid);
set_state(m_stop_state);
m_stop_state = State::Invalid;
}

auto handler_vaddr = action.handler_or_sigaction;
if (handler_vaddr.is_null()) {
Expand Down
1 change: 1 addition & 0 deletions Kernel/Thread.h
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,7 @@ class Thread {
u32 m_priority_boost { 0 };

u8 m_stop_signal { 0 };
State m_stop_state { Invalid };

bool m_dump_backtrace_on_finalization { false };
bool m_should_die { false };
Expand Down

0 comments on commit 2839bb0

Please sign in to comment.