From 3359e5ab70d5c1a5d29a6bdf1d57df6ab616f592 Mon Sep 17 00:00:00 2001
From: bunnei <bunneidev@gmail.com>
Date: Sat, 21 Nov 2020 02:22:03 -0800
Subject: [PATCH] core: cpu_manager: Fix shutdown crash when closing before
 emulation starts.

---
 src/core/cpu_manager.cpp | 24 +++++++++++++++++-------
 1 file changed, 17 insertions(+), 7 deletions(-)

diff --git a/src/core/cpu_manager.cpp b/src/core/cpu_manager.cpp
index 983210197a..100e90d823 100644
--- a/src/core/cpu_manager.cpp
+++ b/src/core/cpu_manager.cpp
@@ -4,6 +4,7 @@
 
 #include "common/fiber.h"
 #include "common/microprofile.h"
+#include "common/scope_exit.h"
 #include "common/thread.h"
 #include "core/arm/exclusive_monitor.h"
 #include "core/core.h"
@@ -343,6 +344,16 @@ void CpuManager::RunThread(std::size_t core) {
     data.initialized = true;
     const bool sc_sync = !is_async_gpu && !is_multicore;
     bool sc_sync_first_use = sc_sync;
+
+    // Cleanup
+    SCOPE_EXIT({
+        data.host_context->Exit();
+        data.enter_barrier.reset();
+        data.exit_barrier.reset();
+        data.initialized = false;
+        MicroProfileOnThreadExit();
+    });
+
     /// Running
     while (running_mode) {
         data.is_running = false;
@@ -351,6 +362,12 @@ void CpuManager::RunThread(std::size_t core) {
             system.GPU().ObtainContext();
             sc_sync_first_use = false;
         }
+
+        // Abort if emulation was killed before the session really starts
+        if (!system.IsPoweredOn()) {
+            return;
+        }
+
         auto& scheduler = system.Kernel().CurrentScheduler();
         Kernel::Thread* current_thread = scheduler.GetCurrentThread();
         data.is_running = true;
@@ -360,13 +377,6 @@ void CpuManager::RunThread(std::size_t core) {
         data.exit_barrier->Wait();
         data.is_paused = false;
     }
-    /// Time to cleanup
-    data.host_context->Exit();
-    data.enter_barrier.reset();
-    data.exit_barrier.reset();
-    data.initialized = false;
-
-    MicroProfileOnThreadExit();
 }
 
 } // namespace Core