mirror of
https://github.com/libretro/ppsspp.git
synced 2024-11-23 16:19:44 +00:00
Core: Wait for background CPU load on exit.
This prevents crashes when exiting a game while loading is still in progress. See #11516.
This commit is contained in:
parent
5ea935f4bf
commit
670e207c57
@ -258,6 +258,7 @@ bool LoadFile(FileLoader **fileLoaderPtr, std::string *error_string) {
|
||||
}
|
||||
else if (ebootType == IdentifiedFileType::PSP_PS1_PBP) {
|
||||
*error_string = "PS1 EBOOTs are not supported by PPSSPP.";
|
||||
coreState = CORE_ERROR;
|
||||
return false;
|
||||
}
|
||||
std::string path = fileLoader->Path();
|
||||
@ -269,6 +270,7 @@ bool LoadFile(FileLoader **fileLoaderPtr, std::string *error_string) {
|
||||
return Load_PSP_ELF_PBP(fileLoader, error_string);
|
||||
} else {
|
||||
*error_string = "No EBOOT.PBP, misidentified game";
|
||||
coreState = CORE_ERROR;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -347,5 +349,7 @@ bool LoadFile(FileLoader **fileLoaderPtr, std::string *error_string) {
|
||||
*error_string = "Failed to identify file";
|
||||
break;
|
||||
}
|
||||
|
||||
coreState = CORE_ERROR;
|
||||
return false;
|
||||
}
|
||||
|
@ -247,6 +247,7 @@ bool Load_PSP_ISO(FileLoader *fileLoader, std::string *error_string) {
|
||||
} else {
|
||||
*error_string = "A PSP game couldn't be found on the disc.";
|
||||
}
|
||||
coreState = CORE_ERROR;
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -257,6 +258,10 @@ bool Load_PSP_ISO(FileLoader *fileLoader, std::string *error_string) {
|
||||
|
||||
std::thread th([bootpath] {
|
||||
setCurrentThreadName("ExecLoader");
|
||||
PSP_LoadingLock guard;
|
||||
if (coreState != CORE_POWERUP)
|
||||
return;
|
||||
|
||||
PSP_SetLoading("Loading executable...");
|
||||
// TODO: We can't use the initial error_string pointer.
|
||||
bool success = __KernelLoadExec(bootpath.c_str(), 0, &PSP_CoreParameter().errorString);
|
||||
@ -327,6 +332,7 @@ bool Load_PSP_ELF_PBP(FileLoader *fileLoader, std::string *error_string) {
|
||||
// If root is not a subpath of path, we can't boot the game.
|
||||
if (!startsWith(pathNorm, rootNorm)) {
|
||||
*error_string = "Cannot boot ELF located outside mountRoot.";
|
||||
coreState = CORE_ERROR;
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -374,6 +380,11 @@ bool Load_PSP_ELF_PBP(FileLoader *fileLoader, std::string *error_string) {
|
||||
// End of temporary code
|
||||
|
||||
std::thread th([finalName] {
|
||||
setCurrentThreadName("ExecLoader");
|
||||
PSP_LoadingLock guard;
|
||||
if (coreState != CORE_POWERUP)
|
||||
return;
|
||||
|
||||
bool success = __KernelLoadExec(finalName.c_str(), 0, &PSP_CoreParameter().errorString);
|
||||
if (success && coreState == CORE_POWERUP) {
|
||||
coreState = PSP_CoreParameter().startBreak ? CORE_STEPPING : CORE_RUNNING;
|
||||
@ -392,6 +403,11 @@ bool Load_PSP_GE_Dump(FileLoader *fileLoader, std::string *error_string) {
|
||||
pspFileSystem.Mount("disc0:", umd);
|
||||
|
||||
std::thread th([] {
|
||||
setCurrentThreadName("ExecLoader");
|
||||
PSP_LoadingLock guard;
|
||||
if (coreState != CORE_POWERUP)
|
||||
return;
|
||||
|
||||
bool success = __KernelLoadGEDump("disc0:/data.ppdmp", &PSP_CoreParameter().errorString);
|
||||
if (success && coreState == CORE_POWERUP) {
|
||||
coreState = PSP_CoreParameter().startBreak ? CORE_STEPPING : CORE_RUNNING;
|
||||
|
@ -82,6 +82,9 @@ ParamSFOData g_paramSFO;
|
||||
static GlobalUIState globalUIState;
|
||||
static CoreParameter coreParameter;
|
||||
static FileLoader *loadedFile;
|
||||
// For background loading thread.
|
||||
static std::mutex loadingLock;
|
||||
// For loadingReason updates.
|
||||
static std::mutex loadingReasonLock;
|
||||
static std::string loadingReason;
|
||||
|
||||
@ -255,7 +258,18 @@ void CPU_Init() {
|
||||
}
|
||||
}
|
||||
|
||||
PSP_LoadingLock::PSP_LoadingLock() {
|
||||
loadingLock.lock();
|
||||
}
|
||||
|
||||
PSP_LoadingLock::~PSP_LoadingLock() {
|
||||
loadingLock.unlock();
|
||||
}
|
||||
|
||||
void CPU_Shutdown() {
|
||||
// Since we load on a background thread, wait for startup to complete.
|
||||
PSP_LoadingLock lock;
|
||||
|
||||
if (g_Config.bAutoSaveSymbolMap) {
|
||||
host->SaveSymbolMap();
|
||||
}
|
||||
|
@ -79,6 +79,12 @@ void PSP_RunLoopFor(int cycles);
|
||||
void PSP_SetLoading(const std::string &reason);
|
||||
std::string PSP_GetLoading();
|
||||
|
||||
// Used to wait for background loading thread.
|
||||
struct PSP_LoadingLock {
|
||||
PSP_LoadingLock();
|
||||
~PSP_LoadingLock();
|
||||
};
|
||||
|
||||
// Call before PSP_BeginHostFrame() in order to not miss any GPU stats.
|
||||
void Core_UpdateDebugStats(bool collectStats);
|
||||
|
||||
|
@ -334,7 +334,7 @@ void EmuScreen::bootComplete() {
|
||||
}
|
||||
|
||||
EmuScreen::~EmuScreen() {
|
||||
if (!invalid_) {
|
||||
if (!invalid_ || bootPending_) {
|
||||
// If we were invalid, it would already be shutdown.
|
||||
PSP_Shutdown();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user