]> Chaos Git - corbenik/ctrulib.git/commitdiff
Add srvSysInit, srvSysExit - when the srv: port doesn't exist, strange things happen...
authorchaoskagami <chaos.kagami@gmail.com>
Fri, 14 Oct 2016 08:46:20 +0000 (04:46 -0400)
committerchaoskagami <chaos.kagami@gmail.com>
Fri, 14 Oct 2016 08:50:40 +0000 (04:50 -0400)
libctru/include/3ds/srv.h
libctru/source/srv.c

index d121cb1a79c94db6b2115ba6bf63e4024f085b1c..b0a5860a048c0a63ab4cede4ee02fbb1c468c186 100644 (file)
@@ -4,6 +4,12 @@
  */
 #pragma once
 
+/// Initializes the service API in a way that is safe during the boot process.
+Result srvSysInit(void);
+
+/// Deinitializes the service API in a way that is safe from system modules.
+Result srvSysExit(void);
+
 /// Initializes the service API.
 Result srvInit(void);
 
index e5b66526a1afe5e61366193f29cf670a8627c410..0de2e863cb8ac62da9262be4e9eeffe8be342165 100644 (file)
 
 static Handle srvHandle;
 static int srvRefCount;
+static RecursiveLock initLock;
+static int initLockinit = 0;
+
+Result srvSysInit(void)
+{
+       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 = srvRegisterClient();
+               srvRefCount++;
+       }
+
+       RecursiveLock_Unlock(&initLock);
+
+       return rc;
+}
 
 Result srvInit(void)
 {
@@ -37,6 +70,29 @@ void srvExit(void)
        srvHandle = 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); // This should never happen.
+
+       srvHandle = 0;
+       srvRefCount--;
+       RecursiveLock_Unlock(&initLock);
+
+       return rc;
+}
+
 Handle *srvGetSessionHandle(void)
 {
        return &srvHandle;