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());