apt: fix dirty homebrew chainload
Fix chainload method used when HM is not launched. We now wait for custom PM to change our launch flag and ask us to terminate. We previously had a few issues: - a potential race condition where we exit before PM changes our runflags (not observed) - a kernel deadlock between ExitProcess and TerminateProcess (observed, this is due to Nintendo's lack of barrier in many of their atomics code) - debuggers reporting that we were terminated, instead of exiting gracefully (not desirable)
This commit is contained in:
parent
da323fa50b
commit
08b76e2e17
@ -345,6 +345,7 @@ void aptExit(void)
|
|||||||
if (AtomicDecrement(&aptRefCount)) return;
|
if (AtomicDecrement(&aptRefCount)) return;
|
||||||
|
|
||||||
bool closeAptLock = true;
|
bool closeAptLock = true;
|
||||||
|
bool doDirtyChainload = false;
|
||||||
|
|
||||||
if (!aptIsCrippled())
|
if (!aptIsCrippled())
|
||||||
{
|
{
|
||||||
@ -378,7 +379,7 @@ void aptExit(void)
|
|||||||
{
|
{
|
||||||
// XX: HOME menu doesn't exist, so we need to use a workaround provided by Luma3DS
|
// XX: HOME menu doesn't exist, so we need to use a workaround provided by Luma3DS
|
||||||
APT_Finalize(envGetAptAppId());
|
APT_Finalize(envGetAptAppId());
|
||||||
srvPublishToSubscriber(0x3000, 0);
|
doDirtyChainload = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// After a chainload has been applied, we don't need to manually close
|
// After a chainload has been applied, we don't need to manually close
|
||||||
@ -413,6 +414,30 @@ void aptExit(void)
|
|||||||
|
|
||||||
if (closeAptLock)
|
if (closeAptLock)
|
||||||
svcCloseHandle(aptLockHandle);
|
svcCloseHandle(aptLockHandle);
|
||||||
|
|
||||||
|
if (doDirtyChainload)
|
||||||
|
{
|
||||||
|
// Provided by Luma3DS
|
||||||
|
Handle notificationHandle = 0;
|
||||||
|
Result res = 0;
|
||||||
|
u32 notificationNumber = 0;
|
||||||
|
srvEnableNotification(¬ificationHandle);
|
||||||
|
|
||||||
|
// Not needed, but official (sysmodule) code does this:
|
||||||
|
srvSubscribe(0x100);
|
||||||
|
|
||||||
|
// Make PM modify our run flags and ask us to terminate
|
||||||
|
srvPublishToSubscriber(0x3000, 0);
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
// Bail out after 3 seconds, we don't want to wait forever for this
|
||||||
|
res = svcWaitSynchronization(notificationHandle, 3 * 1000 * 1000LL);
|
||||||
|
res = res == 0 ? srvReceiveNotification(¬ificationNumber) : res;
|
||||||
|
} while(res == 0 && notificationNumber != 0x100);
|
||||||
|
|
||||||
|
svcCloseHandle(notificationHandle);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void aptEventHandler(void *arg)
|
void aptEventHandler(void *arg)
|
||||||
|
Loading…
Reference in New Issue
Block a user