mirror of
https://github.com/switchbrew/libnx.git
synced 2025-06-25 06:12:40 +02:00
Added env AppletFlags handling. Don't enter the msg-loop for AppletType_Application when the output from _appletGetCurrentFocusState is already 1. This fixes the hang issue with AppletType_Application where applet init with AppletType_Application was previously done. Moved AppletType_*Application checks into a dedicated function which also checks for AppletType_SystemApplication, hence some of these funcs which didn't check for AppletType_SystemApplication now support it.
This commit is contained in:
parent
96dce1a8b6
commit
b4859873ec
@ -35,6 +35,10 @@ enum {
|
||||
EntryType_LastLoadResult=11 ///< Provides the last load result.
|
||||
};
|
||||
|
||||
enum {
|
||||
EnvAppletFlags_ApplicationOverride = BIT(0) ///< Use AppletType_Application instead of AppletType_SystemApplication.
|
||||
};
|
||||
|
||||
/// Loader return function.
|
||||
typedef void NORETURN (*LoaderReturnFn)(int result_code);
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "runtime/env.h"
|
||||
#include "services/sm.h"
|
||||
#include "services/fatal.h"
|
||||
#include "services/applet.h"
|
||||
|
||||
void NORETURN __nx_exit(Result rc, LoaderReturnFn retaddr);
|
||||
|
||||
@ -79,6 +80,7 @@ void envSetup(void* ctx, Handle main_thread, LoaderReturnFn saved_lr)
|
||||
|
||||
case EntryType_AppletType:
|
||||
__nx_applet_type = ent->Value[0];
|
||||
if ((ent->Value[1] & EnvAppletFlags_ApplicationOverride) && __nx_applet_type == AppletType_SystemApplication) __nx_applet_type = AppletType_Application;
|
||||
break;
|
||||
|
||||
case EntryType_ProcessHandle:
|
||||
|
@ -186,30 +186,34 @@ Result appletInitialize(void)
|
||||
|
||||
if (R_SUCCEEDED(rc) && (__nx_applet_type == AppletType_Application))
|
||||
{
|
||||
do {
|
||||
svcWaitSynchronizationSingle(g_appletMessageEventHandle, U64_MAX);
|
||||
//When applet was previously initialized in the context of the current process for AppletType_Application, there's exactly 1 issue with initializing again: this loop hangs since there's no message available. If a timeout is added to the above waitsync where the loop is exited on timeout when _appletGetCurrentFocusState output is 1, initialization works fine.
|
||||
rc = _appletGetCurrentFocusState(&g_appletFocusState);
|
||||
|
||||
u32 msg;
|
||||
rc = _appletReceiveMessage(&msg);
|
||||
//Don't enter this msg-loop when g_appletFocusState is already 1, it will hang when applet was previously initialized in the context of the current process for AppletType_Application.
|
||||
if (R_SUCCEEDED(rc) && g_appletFocusState!=1) {
|
||||
do {
|
||||
svcWaitSynchronizationSingle(g_appletMessageEventHandle, U64_MAX);
|
||||
|
||||
if (R_FAILED(rc))
|
||||
{
|
||||
if ((rc & 0x3fffff) == 0x680)
|
||||
u32 msg;
|
||||
rc = _appletReceiveMessage(&msg);
|
||||
|
||||
if (R_FAILED(rc))
|
||||
{
|
||||
if ((rc & 0x3fffff) == 0x680)
|
||||
continue;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (msg != 0xF)
|
||||
continue;
|
||||
|
||||
break;
|
||||
}
|
||||
rc = _appletGetCurrentFocusState(&g_appletFocusState);
|
||||
|
||||
if (msg != 0xF)
|
||||
continue;
|
||||
if (R_FAILED(rc))
|
||||
break;
|
||||
|
||||
rc = _appletGetCurrentFocusState(&g_appletFocusState);
|
||||
|
||||
if (R_FAILED(rc))
|
||||
break;
|
||||
|
||||
} while(g_appletFocusState!=1);
|
||||
} while(g_appletFocusState!=1);
|
||||
}
|
||||
|
||||
if (R_SUCCEEDED(rc))
|
||||
rc = _appletAcquireForegroundRights();
|
||||
@ -260,13 +264,16 @@ static void NORETURN _appletExitProcess(int result_code) {
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
static bool _appletIsApplication(void) {
|
||||
return __nx_applet_type == AppletType_Application || __nx_applet_type == AppletType_SystemApplication;
|
||||
}
|
||||
|
||||
void appletExit(void)
|
||||
{
|
||||
if (atomicDecrement64(&g_refCnt) == 0)
|
||||
{
|
||||
if ((envIsNso() && __nx_applet_exit_mode==0) || __nx_applet_exit_mode==1) {
|
||||
if (__nx_applet_type == AppletType_Application ||
|
||||
__nx_applet_type == AppletType_SystemApplication ||
|
||||
if (_appletIsApplication() ||
|
||||
__nx_applet_type == AppletType_LibraryApplet) {
|
||||
if (!g_appletExitProcessFlag) {
|
||||
g_appletExitProcessFlag = 1;
|
||||
@ -275,7 +282,7 @@ void appletExit(void)
|
||||
return;
|
||||
}
|
||||
else {
|
||||
if (__nx_applet_type == AppletType_Application || __nx_applet_type == AppletType_SystemApplication) {
|
||||
if (_appletIsApplication()) {
|
||||
//_appletSetTerminateResult(0);
|
||||
_appletSelfExit();
|
||||
}
|
||||
@ -564,7 +571,7 @@ Result appletGetDesiredLanguage(u64 *LanguageCode) {
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
|
||||
if (!serviceIsActive(&g_appletSrv) || __nx_applet_type != AppletType_Application)
|
||||
if (!serviceIsActive(&g_appletSrv) || !_appletIsApplication())
|
||||
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||
|
||||
struct {
|
||||
@ -603,8 +610,7 @@ Result appletBeginBlockingHomeButton(s64 val) {
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
|
||||
if (!serviceIsActive(&g_appletSrv) || (__nx_applet_type!=AppletType_Application
|
||||
&& __nx_applet_type!=AppletType_SystemApplication))
|
||||
if (!serviceIsActive(&g_appletSrv) || !_appletIsApplication())
|
||||
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||
|
||||
struct {
|
||||
@ -640,8 +646,7 @@ Result appletEndBlockingHomeButton(void) {
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
|
||||
if (!serviceIsActive(&g_appletSrv) || (__nx_applet_type!=AppletType_Application
|
||||
&& __nx_applet_type!=AppletType_SystemApplication))
|
||||
if (!serviceIsActive(&g_appletSrv) || !_appletIsApplication())
|
||||
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||
|
||||
struct {
|
||||
|
Loading…
Reference in New Issue
Block a user