summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Yuri Kunde Schlesner2015-07-17 02:24:13 -0300
committerGravatar Yuri Kunde Schlesner2015-07-17 02:24:13 -0300
commitdc39d06950de246094be9643313970125e0c49ee (patch)
treee7f43ef1f2ae7b8fd029bdaf6c43c2b25f5620eb /src
parentRemove webchat link from readme (diff)
downloadyuzu-dc39d06950de246094be9643313970125e0c49ee.tar.gz
yuzu-dc39d06950de246094be9643313970125e0c49ee.tar.xz
yuzu-dc39d06950de246094be9643313970125e0c49ee.zip
Ensure all kernel objects are released during shutdown
This commit fixes several kernel object leaks. The most severe of them was threads not being removed from the private handle table used for CoreTiming events. This resulted in Threads never being released, which in turn held references to Process, causing CodeSets to never be freed when loading other applications.
Diffstat (limited to '')
-rw-r--r--src/core/hle/kernel/thread.cpp21
-rw-r--r--src/core/hle/service/apt/apt.cpp3
-rw-r--r--src/core/hle/service/dsp_dsp.cpp5
-rw-r--r--src/core/hle/service/dsp_dsp.h1
-rw-r--r--src/core/hle/service/gsp_gpu.cpp7
-rw-r--r--src/core/hle/service/gsp_gpu.h1
-rw-r--r--src/core/hle/service/nwm_uds.cpp4
-rw-r--r--src/core/hle/service/nwm_uds.h1
-rw-r--r--src/core/hle/service/srv.cpp4
-rw-r--r--src/core/hle/service/srv.h1
-rw-r--r--src/core/hle/service/y2r_u.cpp4
-rw-r--r--src/core/hle/service/y2r_u.h1
12 files changed, 45 insertions, 8 deletions
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index 4729a7fe0..64166ab99 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -37,6 +37,10 @@ void Thread::Acquire() {
37 ASSERT_MSG(!ShouldWait(), "object unavailable!"); 37 ASSERT_MSG(!ShouldWait(), "object unavailable!");
38} 38}
39 39
40// TODO(yuriks): This can be removed if Thread objects are explicitly pooled in the future, allowing
41// us to simply use a pool index or similar.
42static Kernel::HandleTable wakeup_callback_handle_table;
43
40// Lists all thread ids that aren't deleted/etc. 44// Lists all thread ids that aren't deleted/etc.
41static std::vector<SharedPtr<Thread>> thread_list; 45static std::vector<SharedPtr<Thread>> thread_list;
42 46
@@ -93,6 +97,8 @@ void Thread::Stop() {
93 97
94 // Cancel any outstanding wakeup events for this thread 98 // Cancel any outstanding wakeup events for this thread
95 CoreTiming::UnscheduleEvent(ThreadWakeupEventType, callback_handle); 99 CoreTiming::UnscheduleEvent(ThreadWakeupEventType, callback_handle);
100 wakeup_callback_handle_table.Close(callback_handle);
101 callback_handle = 0;
96 102
97 // Clean up thread from ready queue 103 // Clean up thread from ready queue
98 // This is only needed when the thread is termintated forcefully (SVC TerminateProcess) 104 // This is only needed when the thread is termintated forcefully (SVC TerminateProcess)
@@ -108,6 +114,7 @@ void Thread::Stop() {
108 for (auto& wait_object : wait_objects) { 114 for (auto& wait_object : wait_objects) {
109 wait_object->RemoveWaitingThread(this); 115 wait_object->RemoveWaitingThread(this);
110 } 116 }
117 wait_objects.clear();
111 118
112 Kernel::g_current_process->used_tls_slots[tls_index] = false; 119 Kernel::g_current_process->used_tls_slots[tls_index] = false;
113 120
@@ -268,10 +275,6 @@ void WaitCurrentThread_ArbitrateAddress(VAddr wait_address) {
268 thread->status = THREADSTATUS_WAIT_ARB; 275 thread->status = THREADSTATUS_WAIT_ARB;
269} 276}
270 277
271// TODO(yuriks): This can be removed if Thread objects are explicitly pooled in the future, allowing
272// us to simply use a pool index or similar.
273static Kernel::HandleTable wakeup_callback_handle_table;
274
275/** 278/**
276 * Callback that will wake up the thread it was scheduled for 279 * Callback that will wake up the thread it was scheduled for
277 * @param thread_handle The handle of the thread that's been awoken 280 * @param thread_handle The handle of the thread that's been awoken
@@ -503,12 +506,16 @@ void ThreadingInit() {
503 506
504 current_thread = nullptr; 507 current_thread = nullptr;
505 next_thread_id = 1; 508 next_thread_id = 1;
506
507 thread_list.clear();
508 ready_queue.clear();
509} 509}
510 510
511void ThreadingShutdown() { 511void ThreadingShutdown() {
512 current_thread = nullptr;
513
514 for (auto& t : thread_list) {
515 t->Stop();
516 }
517 thread_list.clear();
518 ready_queue.clear();
512} 519}
513 520
514} // namespace 521} // namespace
diff --git a/src/core/hle/service/apt/apt.cpp b/src/core/hle/service/apt/apt.cpp
index b364beed9..7b6ab4ce0 100644
--- a/src/core/hle/service/apt/apt.cpp
+++ b/src/core/hle/service/apt/apt.cpp
@@ -406,6 +406,9 @@ void Shutdown() {
406 lock = nullptr; 406 lock = nullptr;
407 notification_event = nullptr; 407 notification_event = nullptr;
408 parameter_event = nullptr; 408 parameter_event = nullptr;
409
410 next_parameter.object = nullptr;
411
409 HLE::Applets::Shutdown(); 412 HLE::Applets::Shutdown();
410} 413}
411 414
diff --git a/src/core/hle/service/dsp_dsp.cpp b/src/core/hle/service/dsp_dsp.cpp
index fafb43a2f..a8cb15d60 100644
--- a/src/core/hle/service/dsp_dsp.cpp
+++ b/src/core/hle/service/dsp_dsp.cpp
@@ -310,4 +310,9 @@ Interface::Interface() {
310 Register(FunctionTable); 310 Register(FunctionTable);
311} 311}
312 312
313Interface::~Interface() {
314 semaphore_event = nullptr;
315 interrupt_event = nullptr;
316}
317
313} // namespace 318} // namespace
diff --git a/src/core/hle/service/dsp_dsp.h b/src/core/hle/service/dsp_dsp.h
index 54109b2a9..b6f611db5 100644
--- a/src/core/hle/service/dsp_dsp.h
+++ b/src/core/hle/service/dsp_dsp.h
@@ -16,6 +16,7 @@ namespace DSP_DSP {
16class Interface : public Service::Interface { 16class Interface : public Service::Interface {
17public: 17public:
18 Interface(); 18 Interface();
19 ~Interface() override;
19 20
20 std::string GetPortName() const override { 21 std::string GetPortName() const override {
21 return "dsp::DSP"; 22 return "dsp::DSP";
diff --git a/src/core/hle/service/gsp_gpu.cpp b/src/core/hle/service/gsp_gpu.cpp
index 3910d0227..8b40ba376 100644
--- a/src/core/hle/service/gsp_gpu.cpp
+++ b/src/core/hle/service/gsp_gpu.cpp
@@ -584,7 +584,7 @@ const Interface::FunctionInfo FunctionTable[] = {
584Interface::Interface() { 584Interface::Interface() {
585 Register(FunctionTable); 585 Register(FunctionTable);
586 586
587 g_interrupt_event = 0; 587 g_interrupt_event = nullptr;
588 588
589 using Kernel::MemoryPermission; 589 using Kernel::MemoryPermission;
590 g_shared_memory = Kernel::SharedMemory::Create(0x1000, MemoryPermission::ReadWrite, 590 g_shared_memory = Kernel::SharedMemory::Create(0x1000, MemoryPermission::ReadWrite,
@@ -593,4 +593,9 @@ Interface::Interface() {
593 g_thread_id = 0; 593 g_thread_id = 0;
594} 594}
595 595
596Interface::~Interface() {
597 g_interrupt_event = nullptr;
598 g_shared_memory = nullptr;
599}
600
596} // namespace 601} // namespace
diff --git a/src/core/hle/service/gsp_gpu.h b/src/core/hle/service/gsp_gpu.h
index 268089fdd..c89d0a467 100644
--- a/src/core/hle/service/gsp_gpu.h
+++ b/src/core/hle/service/gsp_gpu.h
@@ -161,6 +161,7 @@ static_assert(sizeof(CommandBuffer) == 0x200, "CommandBuffer struct has incorrec
161class Interface : public Service::Interface { 161class Interface : public Service::Interface {
162public: 162public:
163 Interface(); 163 Interface();
164 ~Interface() override;
164 165
165 std::string GetPortName() const override { 166 std::string GetPortName() const override {
166 return "gsp::Gpu"; 167 return "gsp::Gpu";
diff --git a/src/core/hle/service/nwm_uds.cpp b/src/core/hle/service/nwm_uds.cpp
index 25b01860e..18b22956f 100644
--- a/src/core/hle/service/nwm_uds.cpp
+++ b/src/core/hle/service/nwm_uds.cpp
@@ -125,4 +125,8 @@ Interface::Interface() {
125 Register(FunctionTable); 125 Register(FunctionTable);
126} 126}
127 127
128Interface::~Interface() {
129 handle_event = nullptr;
130}
131
128} // namespace 132} // namespace
diff --git a/src/core/hle/service/nwm_uds.h b/src/core/hle/service/nwm_uds.h
index 82abdff28..0ced2359c 100644
--- a/src/core/hle/service/nwm_uds.h
+++ b/src/core/hle/service/nwm_uds.h
@@ -16,6 +16,7 @@ namespace NWM_UDS {
16class Interface : public Service::Interface { 16class Interface : public Service::Interface {
17public: 17public:
18 Interface(); 18 Interface();
19 ~Interface() override;
19 20
20 std::string GetPortName() const override { 21 std::string GetPortName() const override {
21 return "nwm::UDS"; 22 return "nwm::UDS";
diff --git a/src/core/hle/service/srv.cpp b/src/core/hle/service/srv.cpp
index 6c49fa6cf..3b8c7c0e4 100644
--- a/src/core/hle/service/srv.cpp
+++ b/src/core/hle/service/srv.cpp
@@ -68,4 +68,8 @@ Interface::Interface() {
68 Register(FunctionTable); 68 Register(FunctionTable);
69} 69}
70 70
71Interface::~Interface() {
72 event_handle = nullptr;
73}
74
71} // namespace 75} // namespace
diff --git a/src/core/hle/service/srv.h b/src/core/hle/service/srv.h
index 653aba5cb..96c89b025 100644
--- a/src/core/hle/service/srv.h
+++ b/src/core/hle/service/srv.h
@@ -13,6 +13,7 @@ namespace SRV {
13class Interface : public Service::Interface { 13class Interface : public Service::Interface {
14public: 14public:
15 Interface(); 15 Interface();
16 ~Interface() override;
16 17
17 std::string GetPortName() const override { 18 std::string GetPortName() const override {
18 return "srv:"; 19 return "srv:";
diff --git a/src/core/hle/service/y2r_u.cpp b/src/core/hle/service/y2r_u.cpp
index e121a54e3..6e7dafaad 100644
--- a/src/core/hle/service/y2r_u.cpp
+++ b/src/core/hle/service/y2r_u.cpp
@@ -410,4 +410,8 @@ Interface::Interface() {
410 Register(FunctionTable); 410 Register(FunctionTable);
411} 411}
412 412
413Interface::~Interface() {
414 completion_event = nullptr;
415}
416
413} // namespace 417} // namespace
diff --git a/src/core/hle/service/y2r_u.h b/src/core/hle/service/y2r_u.h
index 9454e5aab..3965a5545 100644
--- a/src/core/hle/service/y2r_u.h
+++ b/src/core/hle/service/y2r_u.h
@@ -112,6 +112,7 @@ struct ConversionConfiguration {
112class Interface : public Service::Interface { 112class Interface : public Service::Interface {
113public: 113public:
114 Interface(); 114 Interface();
115 ~Interface() override;
115 116
116 std::string GetPortName() const override { 117 std::string GetPortName() const override {
117 return "y2r:u"; 118 return "y2r:u";