Result srvSysInit() { Result rc = 0; if (!initLockinit) { RecursiveLock_Init(&initLock); } RecursiveLock_Lock(&initLock); if (srvRefCount > 0) { RecursiveLock_Unlock(&initLock); return MAKERESULT(RL_INFO, RS_NOP, 25, RD_ALREADY_INITIALIZED); } while (1) { rc = svcConnectToPort(&srvHandle, "srv:"); if (R_LEVEL(rc) != RL_PERMANENT || R_SUMMARY(rc) != RS_NOTFOUND || R_DESCRIPTION(rc) != RD_NOT_FOUND) break; svcSleepThread(500000); } if (R_SUCCEEDED(rc)) { rc = srvSysRegisterClient(); srvRefCount++; } RecursiveLock_Unlock(&initLock); return rc; }
int main(void) { Handle handles[10] = {0}; //notification handle + service handles MyThread receiverThread = {0}, senderThread = {0}, PXISRV11HandlerThread = {0}; for(u32 i = 0; i < 9; i++) assertSuccess(srvRegisterService(handles + 1 + i, serviceNames[i], 1)); assertSuccess(MyThread_Create(&receiverThread, receiver, receiverStack, THREAD_STACK_SIZE, 0x2D, -2)); assertSuccess(MyThread_Create(&senderThread, sender, senderStack, THREAD_STACK_SIZE, 0x2D, -2)); assertSuccess(MyThread_Create(&PXISRV11HandlerThread, PXISRV11Handler, PXISRV11HandlerStack, THREAD_STACK_SIZE, 0x2D, -2)); assertSuccess(srvEnableNotification(&handles[0])); while(!shouldTerminate) { s32 index = 0; assertSuccess(svcWaitSynchronizationN(&index, handles, 10, false, -1LL)); if(index == 0) { u32 notificationId; assertSuccess(srvReceiveNotification(¬ificationId)); if(notificationId == 0x100) shouldTerminate = true; } else { Handle session = 0; SessionData *data = &sessionManager.sessionData[index - 1]; assertSuccess(svcAcceptSession(&session, handles[index])); RecursiveLock_Lock(&sessionManager.senderLock); if(data->handle != 0) svcBreak(USERBREAK_PANIC); data->handle = session; assertSuccess(svcSignalEvent(sessionManager.sendAllBuffersToArm9Event)); RecursiveLock_Unlock(&sessionManager.senderLock); } } u32 PXIMC_OnPXITerminate = 0x10000; //TODO: see if this is correct sessionManager.sessionData[0].state = STATE_SENT_TO_ARM9; sendPXICmdbuf(NULL, 0, &PXIMC_OnPXITerminate); assertSuccess(MyThread_Join(&receiverThread, -1LL)); assertSuccess(MyThread_Join(&senderThread, -1LL)); assertSuccess(MyThread_Join(&PXISRV11HandlerThread, -1LL)); for(u32 i = 0; i < 10; i++) svcCloseHandle(handles[i]); return 0; }
Result srvSysExit() { Result rc; RecursiveLock_Lock(&initLock); if (srvRefCount > 1) { srvRefCount--; RecursiveLock_Unlock(&initLock); return MAKERESULT(RL_INFO, RS_NOP, 25, RD_BUSY); } if (srvHandle != 0) svcCloseHandle(srvHandle); else svcBreak(USERBREAK_ASSERT); rc = (Result)srvHandle; // yeah, I think this is a benign bug srvHandle = 0; srvRefCount--; RecursiveLock_Unlock(&initLock); return rc; }