diff options
author | Yuri Kunde Schlesner <yuriks@yuriks.net> | 2015-01-31 23:26:16 -0200 |
---|---|---|
committer | Yuri Kunde Schlesner <yuriks@yuriks.net> | 2015-02-02 15:37:08 -0200 |
commit | 52f58e64efbf43c114f701eb8f39fb463138ffb8 (patch) | |
tree | eb40cc649b524febe841e463d6de7bce025a8105 /src/core/hle/kernel/kernel.cpp | |
parent | 7725256f649719dcce2c50ea84e79d6199dd9a50 (diff) |
Kernel: Make WaitObjects share ownership of Threads waiting on them
During normal operation, a thread waiting on an WaitObject and the
object hold mutual references to each other for the duration of the
wait.
If a process is forcefully terminated (The CTR kernel has a SVC to do
this, TerminateProcess, though no equivalent exists for threads.) its
threads would also be stopped and destroyed, leaving dangling pointers
in the WaitObjects.
The solution is to simply have the Thread remove itself from WaitObjects
when it is stopped. The vector of Threads in WaitObject has also been
changed to hold SharedPtrs, just in case. (Better to have a reference
cycle than a crash.)
Diffstat (limited to 'src/core/hle/kernel/kernel.cpp')
-rw-r--r-- | src/core/hle/kernel/kernel.cpp | 8 |
1 files changed, 4 insertions, 4 deletions
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index a24c2f69f6..7e0b9542eb 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -20,10 +20,10 @@ SharedPtr<Thread> g_main_thread = nullptr; HandleTable g_handle_table; u64 g_program_id = 0; -void WaitObject::AddWaitingThread(Thread* thread) { +void WaitObject::AddWaitingThread(SharedPtr<Thread> thread) { auto itr = std::find(waiting_threads.begin(), waiting_threads.end(), thread); if (itr == waiting_threads.end()) - waiting_threads.push_back(thread); + waiting_threads.push_back(std::move(thread)); } void WaitObject::RemoveWaitingThread(Thread* thread) { @@ -32,11 +32,11 @@ void WaitObject::RemoveWaitingThread(Thread* thread) { waiting_threads.erase(itr); } -Thread* WaitObject::WakeupNextThread() { +SharedPtr<Thread> WaitObject::WakeupNextThread() { if (waiting_threads.empty()) return nullptr; - auto next_thread = waiting_threads.front(); + auto next_thread = std::move(waiting_threads.front()); waiting_threads.erase(waiting_threads.begin()); next_thread->ReleaseWaitObject(this); |