1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-30 19:38:12 +00:00

Kernel: Port wait to ThreadBlocker

This commit is contained in:
Robin Burchell 2019-07-18 18:05:19 +02:00 committed by Andreas Kling
parent 4f9ae9b970
commit 782e4ee6e1
4 changed files with 43 additions and 31 deletions

View file

@ -172,11 +172,39 @@ bool Thread::ThreadBlockerSelect::should_unblock(Thread& thread, time_t now_sec,
return false;
}
Thread::ThreadBlockerWait::ThreadBlockerWait(int wait_options, pid_t& waitee_pid)
: m_wait_options(wait_options)
, m_waitee_pid(waitee_pid)
{
}
bool Thread::ThreadBlockerWait::should_unblock(Thread& thread, time_t, long)
{
bool should_unblock = false;
thread.process().for_each_child([&](Process& child) {
if (m_waitee_pid != -1 && m_waitee_pid != child.pid())
return IterationDecision::Continue;
bool child_exited = child.is_dead();
bool child_stopped = child.main_thread().state() == Thread::State::Stopped;
bool wait_finished = ((m_wait_options & WEXITED) && child_exited)
|| ((m_wait_options & WSTOPPED) && child_stopped);
if (!wait_finished)
return IterationDecision::Continue;
m_waitee_pid = child.pid();
should_unblock = true;
return IterationDecision::Break;
});
return should_unblock;
}
// Called by the scheduler on threads that are blocked for some reason.
// Make a decision as to whether to unblock them or not.
void Thread::consider_unblock(time_t now_sec, long now_usec)
{
auto& process = this->process();
switch (state()) {
case Thread::__Begin_Blocked_States__:
case Thread::__End_Blocked_States__:
@ -191,25 +219,6 @@ void Thread::consider_unblock(time_t now_sec, long now_usec)
case Thread::BlockedSignal:
/* don't know, don't care */
return;
case Thread::BlockedWait:
process.for_each_child([&](Process& child) {
if (waitee_pid() != -1 && waitee_pid() != child.pid())
return IterationDecision::Continue;
bool child_exited = child.is_dead();
bool child_stopped = child.main_thread().state() == Thread::State::Stopped;
bool wait_finished = ((m_wait_options & WEXITED) && child_exited)
|| ((m_wait_options & WSTOPPED) && child_stopped);
if (!wait_finished)
return IterationDecision::Continue;
m_waitee_pid = child.pid();
unblock();
return IterationDecision::Break;
});
return;
case Thread::BlockedCondition:
ASSERT(m_blocker);
if (m_blocker->should_unblock(*this, now_sec, now_usec)) {