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:
parent
a9db382f0e
commit
dea7f937bf
3 changed files with 37 additions and 17 deletions
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue