From c7dc799e193d1ced47b21465f2e664908ae32ebc Mon Sep 17 00:00:00 2001
From: bunnei <bunneidev@gmail.com>
Date: Mon, 27 Apr 2015 22:12:35 -0400
Subject: [PATCH] Kernel: Properly initialize and shutdown all modules.

---
 src/core/hle/kernel/kernel.cpp | 11 +++++++----
 src/core/hle/kernel/kernel.h   |  5 +++--
 src/core/hle/kernel/thread.cpp | 10 ++++++++--
 src/core/hle/kernel/timer.cpp  |  3 ++-
 4 files changed, 20 insertions(+), 9 deletions(-)

diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index 6261b82b6..fca582bbe 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -14,11 +14,10 @@
 
 namespace Kernel {
 
-unsigned int Object::next_object_id = 0;
-
-SharedPtr<Thread> g_main_thread = nullptr;
+unsigned int Object::next_object_id;
+SharedPtr<Thread> g_main_thread;
 HandleTable g_handle_table;
-u64 g_program_id = 0;
+u64 g_program_id;
 
 void WaitObject::AddWaitingThread(SharedPtr<Thread> thread) {
     auto itr = std::find(waiting_threads.begin(), waiting_threads.end(), thread);
@@ -138,6 +137,10 @@ void HandleTable::Clear() {
 void Init() {
     Kernel::ThreadingInit();
     Kernel::TimersInit();
+
+    Object::next_object_id = 0;
+    g_program_id = 0;
+    g_main_thread = nullptr;
 }
 
 /// Shutdown the kernel
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h
index 2d295ea00..ab06fa025 100644
--- a/src/core/hle/kernel/kernel.h
+++ b/src/core/hle/kernel/kernel.h
@@ -95,12 +95,13 @@ public:
         return false;
     }
 
+public:
+    static unsigned int next_object_id;
+
 private:
     friend void intrusive_ptr_add_ref(Object*);
     friend void intrusive_ptr_release(Object*);
 
-    static unsigned int next_object_id;
-
     unsigned int ref_count = 0;
     unsigned int object_id = next_object_id++;
 };
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index 33d66b986..d678f5f6f 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -23,7 +23,7 @@
 namespace Kernel {
 
 /// Event type for the thread wake up event
-static int ThreadWakeupEventType = -1;
+static int ThreadWakeupEventType;
 
 bool Thread::ShouldWait() {
     return status != THREADSTATUS_DEAD;
@@ -42,7 +42,7 @@ static Common::ThreadQueueList<Thread*, THREADPRIO_LOWEST+1> ready_queue;
 static Thread* current_thread;
 
 // The first available thread id at startup
-static u32 next_thread_id = 1;
+static u32 next_thread_id;
 
 /**
  * Creates a new thread ID
@@ -497,6 +497,12 @@ void Thread::SetWaitSynchronizationOutput(s32 output) {
 void ThreadingInit() {
     ThreadWakeupEventType = CoreTiming::RegisterEvent("ThreadWakeupCallback", ThreadWakeupCallback);
 
+    current_thread = nullptr;
+    next_thread_id = 1;
+
+    thread_list.clear();
+    ready_queue.clear();
+
     // Setup the idle thread
     SetupIdleThread();
 }
diff --git a/src/core/hle/kernel/timer.cpp b/src/core/hle/kernel/timer.cpp
index 1ec2a4b10..36979248d 100644
--- a/src/core/hle/kernel/timer.cpp
+++ b/src/core/hle/kernel/timer.cpp
@@ -12,7 +12,7 @@
 namespace Kernel {
 
 /// The event type of the generic timer callback event
-static int timer_callback_event_type = -1;
+static int timer_callback_event_type;
 // TODO(yuriks): This can be removed if Timer objects are explicitly pooled in the future, allowing
 //               us to simply use a pool index or similar.
 static Kernel::HandleTable timer_callback_handle_table;
@@ -89,6 +89,7 @@ static void TimerCallback(u64 timer_handle, int cycles_late) {
 }
 
 void TimersInit() {
+    timer_callback_handle_table.Clear();
     timer_callback_event_type = CoreTiming::RegisterEvent("TimerCallback", TimerCallback);
 }