mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 06:48:12 +00:00
Kernel: Fix some issues related to fixes and block conditions
Fix some problems with join blocks where the joining thread block condition was added twice, which lead to a crash when trying to unblock that condition a second time. Deferred block condition evaluation by File objects were also not properly keeping the File object alive, which lead to some random crashes and corruption problems. Other problems were caused by the fact that the Queued state didn't handle signals/interruptions consistently. To solve these issues we remove this state entirely, along with Thread::wait_on and change the WaitQueue into a BlockCondition instead. Also, deliver signals even if there isn't going to be a context switch to another thread. Fixes #4336 and #4330
This commit is contained in:
parent
0918d8b1f8
commit
da5cc34ebb
22 changed files with 474 additions and 434 deletions
|
@ -140,9 +140,7 @@ bool Scheduler::pick_next()
|
|||
#ifdef SCHEDULER_RUNNABLE_DEBUG
|
||||
dbg() << "Scheduler[" << Processor::current().id() << "]: Non-runnables:";
|
||||
Scheduler::for_each_nonrunnable([&](Thread& thread) -> IterationDecision {
|
||||
if (thread.state() == Thread::Queued)
|
||||
dbg() << " " << String::format("%-12s", thread.state_string()) << " " << thread << " @ " << String::format("%w", thread.tss().cs) << ":" << String::format("%x", thread.tss().eip) << " Reason: " << (thread.wait_reason() ? thread.wait_reason() : "none");
|
||||
else if (thread.state() == Thread::Dying)
|
||||
if (thread.state() == Thread::Dying)
|
||||
dbg() << " " << String::format("%-12s", thread.state_string()) << " " << thread << " @ " << String::format("%w", thread.tss().cs) << ":" << String::format("%x", thread.tss().eip) << " Finalizable: " << thread.is_finalizable();
|
||||
else
|
||||
dbg() << " " << String::format("%-12s", thread.state_string()) << " " << thread << " @ " << String::format("%w", thread.tss().cs) << ":" << String::format("%x", thread.tss().eip);
|
||||
|
@ -324,14 +322,6 @@ bool Scheduler::context_switch(Thread* thread)
|
|||
thread->did_schedule();
|
||||
|
||||
auto from_thread = Thread::current();
|
||||
|
||||
// Check if we have any signals we should deliver (even if we don't
|
||||
// end up switching to another thread)
|
||||
if (from_thread && from_thread->state() == Thread::Running && from_thread->pending_signals_for_state()) {
|
||||
ScopedSpinLock lock(from_thread->get_lock());
|
||||
from_thread->dispatch_one_pending_signal();
|
||||
}
|
||||
|
||||
if (from_thread == thread)
|
||||
return false;
|
||||
|
||||
|
@ -364,21 +354,31 @@ bool Scheduler::context_switch(Thread* thread)
|
|||
|
||||
// NOTE: from_thread at this point reflects the thread we were
|
||||
// switched from, and thread reflects Thread::current()
|
||||
enter_current(*from_thread);
|
||||
enter_current(*from_thread, false);
|
||||
ASSERT(thread == Thread::current());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Scheduler::enter_current(Thread& prev_thread)
|
||||
void Scheduler::enter_current(Thread& prev_thread, bool is_first)
|
||||
{
|
||||
ASSERT(g_scheduler_lock.is_locked());
|
||||
ASSERT(g_scheduler_lock.own_lock());
|
||||
prev_thread.set_active(false);
|
||||
if (prev_thread.state() == Thread::Dying) {
|
||||
// If the thread we switched from is marked as dying, then notify
|
||||
// the finalizer. Note that as soon as we leave the scheduler lock
|
||||
// the finalizer may free from_thread!
|
||||
notify_finalizer();
|
||||
} else if (!is_first) {
|
||||
// Check if we have any signals we should deliver (even if we don't
|
||||
// end up switching to another thread).
|
||||
auto current_thread = Thread::current();
|
||||
if (!current_thread->is_in_block()) {
|
||||
ScopedSpinLock lock(current_thread->get_lock());
|
||||
if (current_thread->state() == Thread::Running && current_thread->pending_signals_for_state()) {
|
||||
current_thread->dispatch_one_pending_signal();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue