From 032bdf5b113131f38491e5aa756e7487ec7c7d2c Mon Sep 17 00:00:00 2001 From: Maschell Date: Fri, 7 Oct 2022 12:44:59 +0200 Subject: [PATCH] Fix crash when exiting NFW games takes too long --- .../applicationends_function_replacements.cpp | 2 +- .../sdrefcount/sd_function_replacements.cpp | 22 +++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/source/applicationendshook/applicationends_function_replacements.cpp b/source/applicationendshook/applicationends_function_replacements.cpp index 9060701..60fc0cd 100644 --- a/source/applicationendshook/applicationends_function_replacements.cpp +++ b/source/applicationendshook/applicationends_function_replacements.cpp @@ -30,7 +30,7 @@ void ZombiUFix() { * ZombiU doesn't exit properly. It just calls exit(0) after receiving the * request to exit. If exiting takes too long, other threads will run again * and crash for some reason. The (hacky) solution is to set the priority - * of (some) ZombiU threads to something very high. + * of (some) ZombiU threads to something very high (=> low priority). */ if (OSGetTitleID() == 0x000500001010EF00 || // ZombiU EUR OSGetTitleID() == 0x000500001011A700 || // ZombiU EUR diff --git a/source/sdrefcount/sd_function_replacements.cpp b/source/sdrefcount/sd_function_replacements.cpp index 5466d40..228566b 100644 --- a/source/sdrefcount/sd_function_replacements.cpp +++ b/source/sdrefcount/sd_function_replacements.cpp @@ -4,9 +4,31 @@ #include "logger.h" #include #include +#include +#include #include +void NWF_Fix() { + // Some games using the NWF (like Dot Arcade) keep a thread called "PlatformInputAppStateListenerThread" running, + // which will cause a DSI exception if the title is not closing fast enough. + auto *curThread = OSGetCurrentThread(); + __OSLockScheduler(curThread); + int state = OSDisableInterrupts(); + OSThread *t = *((OSThread **) 0x100567F8); + while (t) { + if (std::string_view(t->name) == "PlatformInputAppStateListenerThread") { + t->priority = 0x80; + OSReport("Set priority to %d for thread %08X (%s) to prevent it from running/crashing\n", t->priority, t, t->name); + } + t = t->activeLink.next; + } + OSRestoreInterrupts(state); + __OSUnlockScheduler(curThread); +} + DECL_FUNCTION(void, __PPCExit, uint32_t u1) { + NWF_Fix(); + CallHook(WUMS_HOOK_APPLICATION_ENDS); CallHook(WUMS_HOOK_FINI_WUT_SOCKETS); CallHook(WUMS_HOOK_FINI_WUT_DEVOPTAB);