Permalink
Browse files

Core: Wait for background CPU load on exit.

This prevents crashes when exiting a game while loading is still in
progress.  See #11516.
  • Loading branch information...
unknownbrackets committed Nov 2, 2018
1 parent 5ea935f commit 670e207c5727bf1fdf923d5bb9c0c4ce32d23462
Showing with 41 additions and 1 deletion.
  1. +4 −0 Core/Loaders.cpp
  2. +16 −0 Core/PSPLoaders.cpp
  3. +14 −0 Core/System.cpp
  4. +6 −0 Core/System.h
  5. +1 −1 UI/EmuScreen.cpp
View
@@ -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;
}
View
@@ -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;
View
@@ -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();
}
View
@@ -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);
View
@@ -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();
}

0 comments on commit 670e207

Please sign in to comment.