mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Dialog: Try to recover on double init, report.
This shouldn't be happening, but is - see #14864. Let's report the situation and try to avoid a complete crash.
This commit is contained in:
parent
433daf1ee8
commit
570d84fb86
1 changed files with 33 additions and 10 deletions
|
@ -136,29 +136,43 @@ static int oldStatus = -1;
|
|||
static std::map<int, u32> currentlyLoadedModules;
|
||||
static int volatileUnlockEvent = -1;
|
||||
static HLEHelperThread *accessThread = nullptr;
|
||||
static const char *accessThreadState = "initial";
|
||||
|
||||
static void CleanupDialogThreads() {
|
||||
if (accessThread && accessThread->Stopped()) {
|
||||
delete accessThread;
|
||||
accessThread = nullptr;
|
||||
static void CleanupDialogThreads(bool force = false) {
|
||||
if (accessThread) {
|
||||
if (accessThread->Stopped()) {
|
||||
delete accessThread;
|
||||
accessThread = nullptr;
|
||||
accessThreadState = "cleaned up";
|
||||
} else if (force) {
|
||||
ERROR_LOG_REPORT(SCEUTILITY, "Utility access thread still running, state: %s, dialog=%d/%d", accessThreadState, currentDialogType, currentDialogActive);
|
||||
|
||||
// Try to force shutdown anyway.
|
||||
accessThread->Terminate();
|
||||
delete accessThread;
|
||||
accessThread = nullptr;
|
||||
accessThreadState = "force terminated";
|
||||
// Try to unlock in case other dialog was shutting down.
|
||||
KernelVolatileMemUnlock(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ActivateDialog(UtilityDialogType type) {
|
||||
CleanupDialogThreads();
|
||||
if (!currentDialogActive) {
|
||||
currentDialogType = type;
|
||||
currentDialogActive = true;
|
||||
// So that we log the next one.
|
||||
oldStatus = -1;
|
||||
}
|
||||
CleanupDialogThreads();
|
||||
}
|
||||
|
||||
static void DeactivateDialog() {
|
||||
CleanupDialogThreads();
|
||||
if (currentDialogActive) {
|
||||
currentDialogActive = false;
|
||||
}
|
||||
CleanupDialogThreads();
|
||||
}
|
||||
|
||||
static PSPDialog *CurrentDialog(UtilityDialogType type) {
|
||||
|
@ -241,6 +255,8 @@ void __UtilityDoState(PointerWrap &p) {
|
|||
Do(p, hasAccessThread);
|
||||
if (hasAccessThread) {
|
||||
Do(p, accessThread);
|
||||
if (p.mode == p.MODE_READ)
|
||||
accessThreadState = "from save state";
|
||||
}
|
||||
} else {
|
||||
hasAccessThread = false;
|
||||
|
@ -250,6 +266,7 @@ void __UtilityDoState(PointerWrap &p) {
|
|||
accessThread->Forget();
|
||||
delete accessThread;
|
||||
accessThread = nullptr;
|
||||
accessThreadState = "cleared from save state";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -264,6 +281,7 @@ void __UtilityShutdown() {
|
|||
if (accessThread) {
|
||||
delete accessThread;
|
||||
accessThread = nullptr;
|
||||
accessThreadState = "shutdown";
|
||||
}
|
||||
|
||||
delete saveDialog;
|
||||
|
@ -299,10 +317,10 @@ void UtilityDialogInitialize(UtilityDialogType type, int delayUs, int priority)
|
|||
(u32_le)MIPS_MAKE_SYSCALL("sceUtility", "__UtilityInitDialog"),
|
||||
};
|
||||
|
||||
CleanupDialogThreads();
|
||||
_assert_(accessThread == nullptr);
|
||||
CleanupDialogThreads(true);
|
||||
accessThread = new HLEHelperThread("ScePafJob", insts, (uint32_t)ARRAY_SIZE(insts), priority, 0x200);
|
||||
accessThread->Start(partDelay, 0);
|
||||
accessThreadState = "initializing";
|
||||
}
|
||||
|
||||
void UtilityDialogShutdown(UtilityDialogType type, int delayUs, int priority) {
|
||||
|
@ -325,12 +343,12 @@ void UtilityDialogShutdown(UtilityDialogType type, int delayUs, int priority) {
|
|||
(u32_le)MIPS_MAKE_SYSCALL("sceUtility", "__UtilityFinishDialog"),
|
||||
};
|
||||
|
||||
CleanupDialogThreads();
|
||||
_assert_(accessThread == nullptr);
|
||||
CleanupDialogThreads(true);
|
||||
bool prevInterrupts = __InterruptsEnabled();
|
||||
__DisableInterrupts();
|
||||
accessThread = new HLEHelperThread("ScePafJob", insts, (uint32_t)ARRAY_SIZE(insts), priority, 0x200);
|
||||
accessThread->Start(partDelay, 0);
|
||||
accessThreadState = "shutting down";
|
||||
if (prevInterrupts)
|
||||
__EnableInterrupts();
|
||||
}
|
||||
|
@ -349,6 +367,7 @@ static int UtilityWorkUs(int us) {
|
|||
|
||||
static int UtilityInitDialog(int type) {
|
||||
PSPDialog *dialog = CurrentDialog((UtilityDialogType)type);
|
||||
accessThreadState = "init finished";
|
||||
if (dialog)
|
||||
return hleLogSuccessI(SCEUTILITY, dialog->FinishInit());
|
||||
return hleLogError(SCEUTILITY, 0, "invalid dialog type?");
|
||||
|
@ -356,6 +375,7 @@ static int UtilityInitDialog(int type) {
|
|||
|
||||
static int UtilityFinishDialog(int type) {
|
||||
PSPDialog *dialog = CurrentDialog((UtilityDialogType)type);
|
||||
accessThreadState = "shutdown finished";
|
||||
if (dialog)
|
||||
return hleLogSuccessI(SCEUTILITY, dialog->FinishShutdown());
|
||||
return hleLogError(SCEUTILITY, 0, "invalid dialog type?");
|
||||
|
@ -367,6 +387,9 @@ static int sceUtilitySavedataInitStart(u32 paramAddr) {
|
|||
WARN_LOG(SCEUTILITY, "Yugioh Savedata Correction");
|
||||
if (accessThread) {
|
||||
accessThread->Terminate();
|
||||
delete accessThread;
|
||||
accessThread = nullptr;
|
||||
accessThreadState = "terminated";
|
||||
// Try to unlock in case other dialog was shutting down.
|
||||
KernelVolatileMemUnlock(0);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue