From 2ac075c3dd2a4b2b365f6bda47a6cc9d9251f793 Mon Sep 17 00:00:00 2001 From: Codex Date: Fri, 9 Oct 2026 08:19:22 -0400 Subject: [PATCH] Lifecycle: drain asynchronous boot before shutdown Join the loader before dismantling guest memory, filesystems or graphics state. A failed loader has already shut down the CPU, so skip duplicate cleanup and still complete lifecycle teardown. Clear libretro pending boot and deferred state buffers on unload/reset. This drains an in-progress load; it does not interrupt a blocking backend read. --- Core/System.cpp | 17 +++++++++++++---- libretro/libretro.cpp | 9 +++++++++ 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/Core/System.cpp b/Core/System.cpp index 8e1bbfffe4..d41bc40ca3 100644 --- a/Core/System.cpp +++ b/Core/System.cpp @@ -855,17 +855,25 @@ BootState PollBootState() { } void PSP_Shutdown(bool success) { + // Only the lifecycle owner calls this; the loader uses CPU_Shutdown on + // failure. Finish its accesses before destroying memory or filesystem state. + if (g_loadingThread.joinable()) { + g_loadingThread.join(); + Core_NotifyLifecycle(CoreLifecycle::START_COMPLETE); + } + // Do nothing if we never inited. if (GetBootState() == BootState::Off) { ERROR_LOG(Log::Loader, "Unexpected PSP_Shutdown"); return; } - _assert_(GetBootState() != BootState::Failed); + // A failed loader already shut its CPU state down. Do not do that twice. + const bool cpuInitialized = GetBootState() != BootState::Failed; Core_Stop(); - if (g_Config.bFuncHashMap) { + if (cpuInitialized && g_Config.bFuncHashMap) { MIPSAnalyst::StoreHashMap(); } @@ -876,7 +884,8 @@ void PSP_Shutdown(bool success) { Core_NotifyLifecycle(CoreLifecycle::STOPPING); - CPU_Shutdown(success); + if (cpuInitialized) + CPU_Shutdown(success); GPU_Shutdown(); g_paramSFO.Clear(); g_paramSFORaw.Clear(); @@ -890,7 +899,7 @@ void PSP_Shutdown(bool success) { Core_NotifyLifecycle(CoreLifecycle::STOPPED); - if (success) { + if (success || !cpuInitialized) { SetBootState(BootState::Off); } diff --git a/libretro/libretro.cpp b/libretro/libretro.cpp index 4ea90a7def..f83b8ec6ae 100644 --- a/libretro/libretro.cpp +++ b/libretro/libretro.cpp @@ -1532,6 +1532,11 @@ void retro_unload_game(void) { } PSP_Shutdown(true); + g_pendingBoot = false; + g_bootErrorString.clear(); + free(unserialize_data); + unserialize_data = nullptr; + unserialize_size = 0; g_VFS.Clear(); delete ctx; @@ -1546,6 +1551,10 @@ void retro_reset(void) { Libretro::EmuThreadStop(); PSP_Shutdown(true); + g_pendingBoot = false; + free(unserialize_data); + unserialize_data = nullptr; + unserialize_size = 0; if (BootState::Complete != PSP_Init(PSP_CoreParameter(), &g_bootErrorString)) { ERROR_LOG(Log::Boot, "%s", g_bootErrorString.c_str());