mirror of
https://github.com/justinian/jsix.git
synced 2025-12-10 00:14:32 -08:00
[kernel] Exit the current thread last on process exit
Previously process::exit() was going through the threads in order calling thread::exit() - which blocks and never wakes if called on the current thread. Since the current thread likely belongs to the process which is exiting, and the current thread wasn't guaranteed to be last in the list, this could leave threads not cleaned up. Worse, no matter what, this caused the m_threads_lock to always be held forever on exit, keeping the scheduler from ever finishing a call to process::thread_exited() on its threads.
This commit is contained in:
@@ -52,20 +52,23 @@ process::create_kernel_process(page_table *pml4)
|
||||
void
|
||||
process::exit(int32_t code)
|
||||
{
|
||||
util::scoped_lock lock {m_threads_lock};
|
||||
|
||||
if (m_state == state::exited)
|
||||
return;
|
||||
|
||||
m_state = state::exited;
|
||||
m_return_code = code;
|
||||
|
||||
thread ¤t = thread::current();
|
||||
|
||||
util::scoped_lock lock {m_threads_lock};
|
||||
for (auto *thread : m_threads) {
|
||||
thread->exit();
|
||||
if (thread != ¤t)
|
||||
thread->exit();
|
||||
}
|
||||
|
||||
if (this == current_cpu().process)
|
||||
scheduler::get().schedule();
|
||||
lock.release();
|
||||
if (¤t.parent() == this)
|
||||
current.exit();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -123,8 +126,7 @@ process::thread_exited(thread *th)
|
||||
delete th;
|
||||
|
||||
// TODO: delete the thread's stack VMA
|
||||
|
||||
if (m_threads.count() == 0) {
|
||||
if (m_threads.empty() && m_state != state::exited) {
|
||||
exit(-1);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -82,6 +82,9 @@ public:
|
||||
/// Get the size of the array.
|
||||
inline count_t count() const { return m_size; }
|
||||
|
||||
/// Check if the array is empty
|
||||
inline bool empty() const { return m_size == 0; }
|
||||
|
||||
/// Get the capacity of the array. This is the amount of space
|
||||
/// actually allocated.
|
||||
inline count_t capacity() const { return m_capacity & cap_mask; }
|
||||
|
||||
Reference in New Issue
Block a user