sm: simplify main loop logic

This commit is contained in:
TuxSH 2019-03-27 20:36:40 +01:00
parent 4a431b8fdf
commit d44055d232

View File

@ -66,7 +66,8 @@ int main(void)
{ {
Result res; Result res;
u32 *cmdbuf = getThreadCommandBuffer(); u32 *cmdbuf = getThreadCommandBuffer();
u32 nbHandles = 3, nbSessions = 0, nbSrvPmSessions = 0; u32 nbHandles = 3, nbSessions = 0;
bool srvPmSessionCreated = false;
Handle clientPortDummy; Handle clientPortDummy;
Handle srvPort, srvPmPort; Handle srvPort, srvPmPort;
@ -90,17 +91,31 @@ int main(void)
for(;;) for(;;)
{ {
s32 id; s32 id = -1;
if(replyTarget == 0) if(replyTarget == 0)
cmdbuf[0] = 0xFFFF0000; // Kernel11 cmdbuf[0] = 0xFFFF0000; // Kernel11
// Rebuild the list
nbHandles = 3;
nbSessions = 0;
for(sessionData = sessionDataInUseList.first; sessionData != NULL; sessionData = sessionData->next)
{
handles[nbHandles++] = sessionData->handle;
nbSessions++;
}
for(sessionData = sessionDataWaitingPortReadyList.first; sessionData != NULL; sessionData = sessionData->next)
{
handles[nbHandles++] = sessionData->busyClientPortHandle;
}
res = svcReplyAndReceive(&id, handles, nbHandles, replyTarget); res = svcReplyAndReceive(&id, handles, nbHandles, replyTarget);
if(res == (Result)0xC920181A) // unreachable remote if(res == (Result)0xC920181A) // unreachable remote
{ {
// Note: if a process has ended, pm will call UnregisterProcess on it // Note: if a process has ended, pm will call UnregisterProcess on it
if(id < 0) if(id < 0)
{ {
for(id = 3; (u32)id < nbHandles && handles[id] != replyTarget; id++); for(id = 0; (u32)id < nbHandles && handles[id] != replyTarget; id++);
if((u32)id >= nbHandles) if((u32)id >= nbHandles)
panic(); panic();
} }
@ -118,30 +133,7 @@ int main(void)
if(sessionData != NULL) if(sessionData != NULL)
{ {
if(sessionData->busyClientPortHandle != 0) // remove unreferenced client port handles from array
{
u32 refCount = 0;
for(u32 i = 0; i < sizeof(sessionDataPool) / sizeof(SessionData); i++)
{
if(sessionDataPool[i].busyClientPortHandle == sessionData->busyClientPortHandle)
++refCount;
}
if(refCount <= 1)
{
u32 i;
for(i = 3 + nbSessions; i < nbHandles && handles[i] == sessionData->busyClientPortHandle; i++);
if(i < nbHandles)
handles[i] = handles[--nbHandles];
}
}
--nbHandles;
for(u32 i = (u32)id; i < nbHandles; i++)
handles[i] = handles[i + 1];
--nbSessions;
svcCloseHandle(sessionData->handle); svcCloseHandle(sessionData->handle);
if(sessionData->isSrvPm)
--nbSrvPmSessions;
moveNode(sessionData, &freeSessionDataList, false); moveNode(sessionData, &freeSessionDataList, false);
} }
else else
@ -163,8 +155,7 @@ int main(void)
} }
} }
svcCloseHandle(handles[id]); // Don't close the handle.
handles[id] = handles[--nbHandles];
} }
replyTarget = 0; replyTarget = 0;
@ -181,26 +172,17 @@ int main(void)
sessionData = (SessionData *)allocateNode(&sessionDataInUseList, &freeSessionDataList, sizeof(SessionData), false); sessionData = (SessionData *)allocateNode(&sessionDataInUseList, &freeSessionDataList, sizeof(SessionData), false);
sessionData->pid = (u32)-1; sessionData->pid = (u32)-1;
sessionData->handle = session; sessionData->handle = session;
for(u32 i = nbHandles; i > 3 + nbSessions; i--)
handles[i] = handles[i - 1];
handles[3 + nbSessions++] = session;
++nbHandles;
} }
else if(id == 2) // New srv:pm session else if(id == 2) // New srv:pm session
{ {
Handle session; Handle session;
if(!IS_PRE_7X && nbSrvPmSessions >= 1) if(!IS_PRE_7X && srvPmSessionCreated)
panic(); panic();
assertSuccess(svcAcceptSession(&session, srvPmPort)); assertSuccess(svcAcceptSession(&session, srvPmPort));
sessionData = (SessionData *)allocateNode(&sessionDataInUseList, &freeSessionDataList, sizeof(SessionData), false); sessionData = (SessionData *)allocateNode(&sessionDataInUseList, &freeSessionDataList, sizeof(SessionData), false);
sessionData->pid = (u32)-1; sessionData->pid = (u32)-1;
sessionData->handle = session; sessionData->handle = session;
sessionData->isSrvPm = true; sessionData->isSrvPm = true;
for(u32 i = nbHandles; i > 3 + nbSessions; i--)
handles[i] = handles[i - 1];
handles[3 + nbSessions++] = session;
++nbHandles;
++nbSrvPmSessions;
} }
else else
{ {
@ -210,31 +192,17 @@ int main(void)
panic(); panic();
sessionData = sessionDataToWakeUpAfterServiceOrPortRegisterList.first; sessionData = sessionDataToWakeUpAfterServiceOrPortRegisterList.first;
moveNode(sessionData, &sessionDataInUseList, false); moveNode(sessionData, &sessionDataInUseList, false);
for(u32 i = nbHandles; i > 3 + nbSessions; i--)
handles[i] = handles[i - 1];
handles[3 + nbSessions++] = sessionData->handle;
++nbHandles;
if(sessionData->isSrvPm)
++nbSrvPmSessions;
memcpy(cmdbuf, sessionData->replayCmdbuf, 16); memcpy(cmdbuf, sessionData->replayCmdbuf, 16);
} }
else if((u32)id >= 3 + nbSessions) // Resume SRV:GetServiceHandle if service was full else if((u32)id >= 3 + nbSessions) // Resume SRV:GetServiceHandle if service was full
{ {
SessionData *sTmp;
for(sessionData = sessionDataWaitingPortReadyList.first; sessionData != NULL && sessionData->busyClientPortHandle != handles[id]; for(sessionData = sessionDataWaitingPortReadyList.first; sessionData != NULL && sessionData->busyClientPortHandle != handles[id];
sessionData = sessionData->next); sessionData = sessionData->next);
if(sessionData == NULL) if(sessionData == NULL) {
panic(); // Ignore (client process could have ended) and continue
continue;
}
moveNode(sessionData, &sessionDataInUseList, false); moveNode(sessionData, &sessionDataInUseList, false);
for(sTmp = sessionDataWaitingPortReadyList.first; sTmp != NULL && sTmp->busyClientPortHandle != handles[id]; sTmp = sTmp->next);
if(sTmp == NULL)
handles[id] = handles[--nbHandles];
for(u32 i = nbHandles + 1; i > 3 + nbSessions; i--)
handles[i] = handles[i - 1];
handles[3 + nbSessions++] = sessionData->handle;
++nbHandles;
if(sessionData->isSrvPm)
++nbSrvPmSessions;
memcpy(cmdbuf, sessionData->replayCmdbuf, 16); memcpy(cmdbuf, sessionData->replayCmdbuf, 16);
sessionData->busyClientPortHandle = 0; sessionData->busyClientPortHandle = 0;
} }
@ -245,10 +213,6 @@ int main(void)
panic(); panic();
} }
for(id = 3; (u32)id < 3 + nbSessions && handles[id] != sessionData->handle; id++);
if((u32)id >= 3 + nbSessions)
panic();
res = sessionData->isSrvPm ? srvPmHandleCommands(sessionData) : srvHandleCommands(sessionData); res = sessionData->isSrvPm ? srvPmHandleCommands(sessionData) : srvHandleCommands(sessionData);
if(R_MODULE(res) == RM_SRV && R_SUMMARY(res) == RS_WOULDBLOCK) if(R_MODULE(res) == RM_SRV && R_SUMMARY(res) == RS_WOULDBLOCK)
@ -257,22 +221,10 @@ int main(void)
if(res == (Result)0xD0406401) // service or named port not registered yet if(res == (Result)0xD0406401) // service or named port not registered yet
dstList = &sessionDataWaitingForServiceOrPortRegisterList; dstList = &sessionDataWaitingForServiceOrPortRegisterList;
else if(res == (Result)0xD0406402) // service full else if(res == (Result)0xD0406402) // service full
{
u32 i;
dstList = &sessionDataWaitingPortReadyList; dstList = &sessionDataWaitingPortReadyList;
for(i = 3 + nbSessions; i < nbHandles && handles[i] != sessionData->busyClientPortHandle; i++);
if(i >= nbHandles)
handles[nbHandles++] = sessionData->busyClientPortHandle;
}
else else
panic(); panic();
--nbHandles;
for(u32 i = (u32)id; i < nbHandles; i++)
handles[i] = handles[i + 1];
--nbSessions;
if(sessionData->isSrvPm)
--nbSrvPmSessions;
moveNode(sessionData, dstList, true); moveNode(sessionData, dstList, true);
} }
else else