Merge pull request #937 from yuriks/codeset-leak
Ensure all kernel objects are released during shutdown
This commit is contained in:
commit
32be6a4553
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThreadingShutdown() {
|
||||||
|
current_thread = nullptr;
|
||||||
|
|
||||||
|
for (auto& t : thread_list) {
|
||||||
|
t->Stop();
|
||||||
|
}
|
||||||
thread_list.clear();
|
thread_list.clear();
|
||||||
ready_queue.clear();
|
ready_queue.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ThreadingShutdown() {
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -310,4 +310,9 @@ Interface::Interface() {
|
||||||
Register(FunctionTable);
|
Register(FunctionTable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Interface::~Interface() {
|
||||||
|
semaphore_event = nullptr;
|
||||||
|
interrupt_event = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -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";
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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";
|
||||||
|
|
|
@ -125,4 +125,8 @@ Interface::Interface() {
|
||||||
Register(FunctionTable);
|
Register(FunctionTable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Interface::~Interface() {
|
||||||
|
handle_event = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -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";
|
||||||
|
|
|
@ -68,4 +68,8 @@ Interface::Interface() {
|
||||||
Register(FunctionTable);
|
Register(FunctionTable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Interface::~Interface() {
|
||||||
|
event_handle = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -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:";
|
||||||
|
|
|
@ -410,4 +410,8 @@ Interface::Interface() {
|
||||||
Register(FunctionTable);
|
Register(FunctionTable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Interface::~Interface() {
|
||||||
|
completion_event = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -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";
|
||||||
|
|
Reference in New Issue