Просмотр исходного кода

Merge pull request #937 from yuriks/codeset-leak

Ensure all kernel objects are released during shutdown
bunnei 11 лет назад
Родитель
Сommit
32be6a4553

+ 14 - 7
src/core/hle/kernel/thread.cpp

@@ -37,6 +37,10 @@ void Thread::Acquire() {
     ASSERT_MSG(!ShouldWait(), "object unavailable!");
     ASSERT_MSG(!ShouldWait(), "object unavailable!");
 }
 }
 
 
+// TODO(yuriks): This can be removed if Thread objects are explicitly pooled in the future, allowing
+//               us to simply use a pool index or similar.
+static Kernel::HandleTable wakeup_callback_handle_table;
+
 // Lists all thread ids that aren't deleted/etc.
 // Lists all thread ids that aren't deleted/etc.
 static std::vector<SharedPtr<Thread>> thread_list;
 static std::vector<SharedPtr<Thread>> thread_list;
 
 
@@ -93,6 +97,8 @@ void Thread::Stop() {
 
 
     // Cancel any outstanding wakeup events for this thread
     // Cancel any outstanding wakeup events for this thread
     CoreTiming::UnscheduleEvent(ThreadWakeupEventType, callback_handle);
     CoreTiming::UnscheduleEvent(ThreadWakeupEventType, callback_handle);
+    wakeup_callback_handle_table.Close(callback_handle);
+    callback_handle = 0;
 
 
     // Clean up thread from ready queue
     // Clean up thread from ready queue
     // This is only needed when the thread is termintated forcefully (SVC TerminateProcess)
     // This is only needed when the thread is termintated forcefully (SVC TerminateProcess)
@@ -108,6 +114,7 @@ void Thread::Stop() {
     for (auto& wait_object : wait_objects) {
     for (auto& wait_object : wait_objects) {
         wait_object->RemoveWaitingThread(this);
         wait_object->RemoveWaitingThread(this);
     }
     }
+    wait_objects.clear();
 
 
     Kernel::g_current_process->used_tls_slots[tls_index] = false;
     Kernel::g_current_process->used_tls_slots[tls_index] = false;
 
 
@@ -268,10 +275,6 @@ void WaitCurrentThread_ArbitrateAddress(VAddr wait_address) {
     thread->status = THREADSTATUS_WAIT_ARB;
     thread->status = THREADSTATUS_WAIT_ARB;
 }
 }
 
 
-// TODO(yuriks): This can be removed if Thread objects are explicitly pooled in the future, allowing
-//               us to simply use a pool index or similar.
-static Kernel::HandleTable wakeup_callback_handle_table;
-
 /**
 /**
  * Callback that will wake up the thread it was scheduled for
  * Callback that will wake up the thread it was scheduled for
  * @param thread_handle The handle of the thread that's been awoken
  * @param thread_handle The handle of the thread that's been awoken
@@ -503,12 +506,16 @@ void ThreadingInit() {
 
 
     current_thread = nullptr;
     current_thread = nullptr;
     next_thread_id = 1;
     next_thread_id = 1;
-
-    thread_list.clear();
-    ready_queue.clear();
 }
 }
 
 
 void ThreadingShutdown() {
 void ThreadingShutdown() {
+    current_thread = nullptr;
+
+    for (auto& t : thread_list) {
+        t->Stop();
+    }
+    thread_list.clear();
+    ready_queue.clear();
 }
 }
 
 
 } // namespace
 } // namespace

+ 3 - 0
src/core/hle/service/apt/apt.cpp

@@ -406,6 +406,9 @@ void Shutdown() {
     lock = nullptr;
     lock = nullptr;
     notification_event = nullptr;
     notification_event = nullptr;
     parameter_event = nullptr;
     parameter_event = nullptr;
+
+    next_parameter.object = nullptr;
+
     HLE::Applets::Shutdown();
     HLE::Applets::Shutdown();
 }
 }
 
 

+ 5 - 0
src/core/hle/service/dsp_dsp.cpp

@@ -310,4 +310,9 @@ Interface::Interface() {
     Register(FunctionTable);
     Register(FunctionTable);
 }
 }
 
 
+Interface::~Interface() {
+    semaphore_event = nullptr;
+    interrupt_event = nullptr;
+}
+
 } // namespace
 } // namespace

+ 1 - 0
src/core/hle/service/dsp_dsp.h

@@ -16,6 +16,7 @@ namespace DSP_DSP {
 class Interface : public Service::Interface {
 class Interface : public Service::Interface {
 public:
 public:
     Interface();
     Interface();
+    ~Interface() override;
 
 
     std::string GetPortName() const override {
     std::string GetPortName() const override {
         return "dsp::DSP";
         return "dsp::DSP";

+ 6 - 1
src/core/hle/service/gsp_gpu.cpp

@@ -584,7 +584,7 @@ const Interface::FunctionInfo FunctionTable[] = {
 Interface::Interface() {
 Interface::Interface() {
     Register(FunctionTable);
     Register(FunctionTable);
 
 
-    g_interrupt_event = 0;
+    g_interrupt_event = nullptr;
 
 
     using Kernel::MemoryPermission;
     using Kernel::MemoryPermission;
     g_shared_memory = Kernel::SharedMemory::Create(0x1000, MemoryPermission::ReadWrite,
     g_shared_memory = Kernel::SharedMemory::Create(0x1000, MemoryPermission::ReadWrite,
@@ -593,4 +593,9 @@ Interface::Interface() {
     g_thread_id = 0;
     g_thread_id = 0;
 }
 }
 
 
+Interface::~Interface() {
+    g_interrupt_event = nullptr;
+    g_shared_memory = nullptr;
+}
+
 } // namespace
 } // namespace

+ 1 - 0
src/core/hle/service/gsp_gpu.h

@@ -161,6 +161,7 @@ static_assert(sizeof(CommandBuffer) == 0x200, "CommandBuffer struct has incorrec
 class Interface : public Service::Interface {
 class Interface : public Service::Interface {
 public:
 public:
     Interface();
     Interface();
+    ~Interface() override;
 
 
     std::string GetPortName() const override {
     std::string GetPortName() const override {
         return "gsp::Gpu";
         return "gsp::Gpu";

+ 4 - 0
src/core/hle/service/nwm_uds.cpp

@@ -125,4 +125,8 @@ Interface::Interface() {
     Register(FunctionTable);
     Register(FunctionTable);
 }
 }
 
 
+Interface::~Interface() {
+    handle_event = nullptr;
+}
+
 } // namespace
 } // namespace

+ 1 - 0
src/core/hle/service/nwm_uds.h

@@ -16,6 +16,7 @@ namespace NWM_UDS {
 class Interface : public Service::Interface {
 class Interface : public Service::Interface {
 public:
 public:
     Interface();
     Interface();
+    ~Interface() override;
 
 
     std::string GetPortName() const override {
     std::string GetPortName() const override {
         return "nwm::UDS";
         return "nwm::UDS";

+ 4 - 0
src/core/hle/service/srv.cpp

@@ -68,4 +68,8 @@ Interface::Interface() {
     Register(FunctionTable);
     Register(FunctionTable);
 }
 }
 
 
+Interface::~Interface() {
+    event_handle = nullptr;
+}
+
 } // namespace
 } // namespace

+ 1 - 0
src/core/hle/service/srv.h

@@ -13,6 +13,7 @@ namespace SRV {
 class Interface : public Service::Interface {
 class Interface : public Service::Interface {
 public:
 public:
     Interface();
     Interface();
+    ~Interface() override;
 
 
     std::string GetPortName() const override {
     std::string GetPortName() const override {
         return "srv:";
         return "srv:";

+ 4 - 0
src/core/hle/service/y2r_u.cpp

@@ -410,4 +410,8 @@ Interface::Interface() {
     Register(FunctionTable);
     Register(FunctionTable);
 }
 }
 
 
+Interface::~Interface() {
+    completion_event = nullptr;
+}
+
 } // namespace
 } // namespace

+ 1 - 0
src/core/hle/service/y2r_u.h

@@ -112,6 +112,7 @@ struct ConversionConfiguration {
 class Interface : public Service::Interface {
 class Interface : public Service::Interface {
 public:
 public:
     Interface();
     Interface();
+    ~Interface() override;
 
 
     std::string GetPortName() const override {
     std::string GetPortName() const override {
         return "y2r:u";
         return "y2r:u";