diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp
index 1a47fb9c96..642f966908 100644
--- a/src/yuzu/bootmanager.cpp
+++ b/src/yuzu/bootmanager.cpp
@@ -79,6 +79,11 @@ void EmuThread::run() {
 
     system.GetCpuManager().OnGpuReady();
 
+    system.RegisterExitCallback([this]() {
+        stop_source.request_stop();
+        SetRunning(false);
+    });
+
     // Holds whether the cpu was running during the last iteration,
     // so that the DebugModeLeft signal can be emitted before the
     // next execution step
diff --git a/src/yuzu/bootmanager.h b/src/yuzu/bootmanager.h
index f4deae4ee3..f0edad6e4c 100644
--- a/src/yuzu/bootmanager.h
+++ b/src/yuzu/bootmanager.h
@@ -84,9 +84,10 @@ public:
     }
 
     /**
-     * Requests for the emulation thread to stop running
+     * Requests for the emulation thread to immediately stop running
      */
-    void RequestStop() {
+    void ForceStop() {
+        LOG_WARNING(Frontend, "Force stopping EmuThread");
         stop_source.request_stop();
         SetRunning(false);
     }
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index df7166d4bc..70552bdb8f 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -1710,9 +1710,6 @@ void GMainWindow::BootGame(const QString& filename, u64 program_id, std::size_t
     system->RegisterExecuteProgramCallback(
         [this](std::size_t program_index_) { render_window->ExecuteProgram(program_index_); });
 
-    // Register an Exit callback such that Core can exit the currently running application.
-    system->RegisterExitCallback([this]() { render_window->Exit(); });
-
     connect(render_window, &GRenderWindow::Closed, this, &GMainWindow::OnStopGame);
     connect(render_window, &GRenderWindow::MouseActivity, this, &GMainWindow::OnMouseActivity);
     // BlockingQueuedConnection is important here, it makes sure we've finished refreshing our views
@@ -1799,12 +1796,16 @@ void GMainWindow::ShutdownGame() {
     system->SetShuttingDown(true);
     system->DetachDebugger();
     discord_rpc->Pause();
-    emu_thread->RequestStop();
+
+    RequestGameExit();
 
     emit EmulationStopping();
 
     // Wait for emulation thread to complete and delete it
-    emu_thread->wait();
+    if (!emu_thread->wait(5000)) {
+        emu_thread->ForceStop();
+        emu_thread->wait();
+    }
     emu_thread = nullptr;
 
     emulation_running = false;