summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/kernel.cpp
diff options
context:
space:
mode:
authorGravatar Yuri Kunde Schlesner2015-01-31 23:26:16 -0200
committerGravatar Yuri Kunde Schlesner2015-02-02 15:37:08 -0200
commit52f58e64efbf43c114f701eb8f39fb463138ffb8 (patch)
treeeb40cc649b524febe841e463d6de7bce025a8105 /src/core/hle/kernel/kernel.cpp
parentExplicitly instantiate constructors/destructors for Kernel objects (diff)
downloadyuzu-52f58e64efbf43c114f701eb8f39fb463138ffb8.tar.gz
yuzu-52f58e64efbf43c114f701eb8f39fb463138ffb8.tar.xz
yuzu-52f58e64efbf43c114f701eb8f39fb463138ffb8.zip
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.cpp8
1 files changed, 4 insertions, 4 deletions
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index a24c2f69f..7e0b9542e 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;
20HandleTable g_handle_table; 20HandleTable g_handle_table;
21u64 g_program_id = 0; 21u64 g_program_id = 0;
22 22
23void WaitObject::AddWaitingThread(Thread* thread) { 23void WaitObject::AddWaitingThread(SharedPtr<Thread> thread) {
24 auto itr = std::find(waiting_threads.begin(), waiting_threads.end(), thread); 24 auto itr = std::find(waiting_threads.begin(), waiting_threads.end(), thread);
25 if (itr == waiting_threads.end()) 25 if (itr == waiting_threads.end())
26 waiting_threads.push_back(thread); 26 waiting_threads.push_back(std::move(thread));
27} 27}
28 28
29void WaitObject::RemoveWaitingThread(Thread* thread) { 29void WaitObject::RemoveWaitingThread(Thread* thread) {
@@ -32,11 +32,11 @@ void WaitObject::RemoveWaitingThread(Thread* thread) {
32 waiting_threads.erase(itr); 32 waiting_threads.erase(itr);
33} 33}
34 34
35Thread* WaitObject::WakeupNextThread() { 35SharedPtr<Thread> WaitObject::WakeupNextThread() {
36 if (waiting_threads.empty()) 36 if (waiting_threads.empty())
37 return nullptr; 37 return nullptr;
38 38
39 auto next_thread = waiting_threads.front(); 39 auto next_thread = std::move(waiting_threads.front());
40 waiting_threads.erase(waiting_threads.begin()); 40 waiting_threads.erase(waiting_threads.begin());
41 41
42 next_thread->ReleaseWaitObject(this); 42 next_thread->ReleaseWaitObject(this);