1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-02 22:22:07 +00:00

Scheduler: Allow reentry into block()

With the presence of signal handlers, it is possible that a thread might
be blocked multiple times. Picture for instance a signal handler using
read(), or wait() while the thread is already blocked elsewhere before
the handler is invoked.

To fix this, we turn m_blocker into a chain of handlers. Each block()
call now prepends to the list, and unblocking will only consider the
most recent (first) blocker in the chain.

Fixes #309
This commit is contained in:
Robin Burchell 2019-07-21 12:14:58 +02:00 committed by Andreas Kling
parent a9db382f0e
commit dea7f937bf
3 changed files with 37 additions and 17 deletions

View file

@ -148,8 +148,8 @@ const char* Thread::state_string() const
case Thread::Skip0SchedulerPasses:
return "Skip0";
case Thread::Blocked:
ASSERT(m_blocker);
return m_blocker->state_string();
ASSERT(!m_blockers.is_empty());
return m_blockers.first()->state_string();
}
kprintf("to_string(Thread::State): Invalid state: %u\n", state());
ASSERT_NOT_REACHED();
@ -539,8 +539,8 @@ void Thread::set_state(State new_state)
{
InterruptDisabler disabler;
if (new_state == Blocked) {
// we should always have an m_blocker while blocked
ASSERT(m_blocker != nullptr);
// we should always have a Blocker while blocked
ASSERT(!m_blockers.is_empty());
}
m_state = new_state;