mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 01:27:43 +00:00
Kernel: Make sure threads which don't do any syscalls are terminated
Steps to reproduce: $ cat loop.c int main() { for (;;); } $ gcc -o loop loop.c $ ./loop Terminating this process wasn't previously possible because we only checked whether the thread should be terminated on syscall exit.
This commit is contained in:
parent
c980a51776
commit
3c3a1726df
3 changed files with 20 additions and 0 deletions
|
@ -192,6 +192,13 @@ bool Scheduler::pick_next()
|
||||||
|
|
||||||
ScopedSpinLock lock(g_scheduler_lock);
|
ScopedSpinLock lock(g_scheduler_lock);
|
||||||
|
|
||||||
|
auto current_thread = Thread::current();
|
||||||
|
if (current_thread->should_die() && current_thread->may_die_immediately()) {
|
||||||
|
// Ordinarily the thread would die on syscall exit, however if the thread
|
||||||
|
// doesn't perform any syscalls we still need to mark it for termination here.
|
||||||
|
current_thread->set_state(Thread::Dying);
|
||||||
|
}
|
||||||
|
|
||||||
if constexpr (SCHEDULER_RUNNABLE_DEBUG) {
|
if constexpr (SCHEDULER_RUNNABLE_DEBUG) {
|
||||||
dump_thread_list();
|
dump_thread_list();
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <AK/ScopeGuard.h>
|
||||||
#include <Kernel/API/Syscall.h>
|
#include <Kernel/API/Syscall.h>
|
||||||
#include <Kernel/Arch/x86/CPU.h>
|
#include <Kernel/Arch/x86/CPU.h>
|
||||||
#include <Kernel/Panic.h>
|
#include <Kernel/Panic.h>
|
||||||
|
@ -129,6 +130,14 @@ NEVER_INLINE void syscall_handler(TrapFrame* trap)
|
||||||
{
|
{
|
||||||
auto& regs = *trap->regs;
|
auto& regs = *trap->regs;
|
||||||
auto current_thread = Thread::current();
|
auto current_thread = Thread::current();
|
||||||
|
{
|
||||||
|
ScopedSpinLock lock(g_scheduler_lock);
|
||||||
|
current_thread->set_may_die_immediately(false);
|
||||||
|
}
|
||||||
|
ScopeGuard reset_may_die_immediately = [¤t_thread] {
|
||||||
|
ScopedSpinLock lock(g_scheduler_lock);
|
||||||
|
current_thread->set_may_die_immediately(true);
|
||||||
|
};
|
||||||
VERIFY(current_thread->previous_mode() == Thread::PreviousMode::UserMode);
|
VERIFY(current_thread->previous_mode() == Thread::PreviousMode::UserMode);
|
||||||
auto& process = current_thread->process();
|
auto& process = current_thread->process();
|
||||||
|
|
||||||
|
|
|
@ -1134,6 +1134,9 @@ public:
|
||||||
bool is_profiling_suppressed() const { return m_is_profiling_suppressed; }
|
bool is_profiling_suppressed() const { return m_is_profiling_suppressed; }
|
||||||
void set_profiling_suppressed() { m_is_profiling_suppressed = true; }
|
void set_profiling_suppressed() { m_is_profiling_suppressed = true; }
|
||||||
|
|
||||||
|
bool may_die_immediately() const { return m_may_die_immediately; }
|
||||||
|
void set_may_die_immediately(bool flag) { m_may_die_immediately = flag; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Thread(NonnullRefPtr<Process>, NonnullOwnPtr<Region>, NonnullRefPtr<Timer>);
|
Thread(NonnullRefPtr<Process>, NonnullOwnPtr<Region>, NonnullRefPtr<Timer>);
|
||||||
|
|
||||||
|
@ -1227,6 +1230,7 @@ private:
|
||||||
Optional<Range> m_thread_specific_range;
|
Optional<Range> m_thread_specific_range;
|
||||||
Array<SignalActionData, NSIG> m_signal_action_data;
|
Array<SignalActionData, NSIG> m_signal_action_data;
|
||||||
Blocker* m_blocker { nullptr };
|
Blocker* m_blocker { nullptr };
|
||||||
|
bool m_may_die_immediately { true };
|
||||||
|
|
||||||
#if LOCK_DEBUG
|
#if LOCK_DEBUG
|
||||||
struct HoldingLockInfo {
|
struct HoldingLockInfo {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue