Introduce atomics.c, refcounting on all services

This commit is contained in:
plutoo 2018-03-10 14:33:40 +01:00
parent d54db1ac16
commit a102c64341
17 changed files with 219 additions and 105 deletions

View File

@ -0,0 +1,6 @@
#include "../types.h"
u32 atomicIncrement32(u32* p);
u32 atomicDecrement32(u32* p);
u64 atomicIncrement64(u64* p);
u64 atomicDecrement64(u64* p);

View File

@ -8,6 +8,8 @@
#include "../types.h" #include "../types.h"
Result pmdmntInitialize(void); Result pmdmntInitialize(void);
void pmdmntExit(void);
Result pmdmntStartProcess(u64 pid); Result pmdmntStartProcess(u64 pid);
Result pmdmntGetTitlePid(u64* pid_out, u64 title_id); Result pmdmntGetTitlePid(u64* pid_out, u64 title_id);
Result pmdmntEnableDebugForTitleId(Handle* handle_out, u64 title_id); Result pmdmntEnableDebugForTitleId(Handle* handle_out, u64 title_id);

17
nx/source/arm/atomics.c Normal file
View File

@ -0,0 +1,17 @@
#include "types.h"
u32 atomicIncrement32(u32* p) {
return __sync_fetch_and_add(p, 1);
}
u32 atomicDecrement32(u32* p) {
return __sync_sub_and_fetch(p, 1);
}
u64 atomicIncrement64(u64* p) {
return __sync_fetch_and_add(p, 1);
}
u64 atomicDecrement64(u64* p) {
return __sync_sub_and_fetch(p, 1);
}

View File

@ -1,19 +1,25 @@
#include "types.h" #include "types.h"
#include "arm/atomics.h"
#include "services/acc.h" #include "services/acc.h"
#include "services/sm.h" #include "services/sm.h"
static Service g_accSrv; static Service g_accSrv;
static u64 g_refCnt;
Result accountInitialize(void) Result accountInitialize(void)
{ {
atomicIncrement64(&g_refCnt);
if (serviceIsActive(&g_accSrv)) if (serviceIsActive(&g_accSrv))
return MAKERESULT(Module_Libnx, LibnxError_AlreadyInitialized); return 0;
return smGetService(&g_accSrv, "acc:u1"); return smGetService(&g_accSrv, "acc:u1");
} }
void accountExit(void) { void accountExit(void)
serviceClose(&g_accSrv); {
if (atomicDecrement64(&g_refCnt) == 0)
serviceClose(&g_accSrv);
} }
Service* accountGetService(void) { Service* accountGetService(void) {

View File

@ -1,18 +1,22 @@
#include "types.h" #include "types.h"
#include "result.h" #include "result.h"
#include "arm/atomics.h"
#include "kernel/ipc.h" #include "kernel/ipc.h"
#include "services/apm.h" #include "services/apm.h"
#include "services/sm.h" #include "services/sm.h"
static Service g_apmSrv; static Service g_apmSrv;
static Service g_apmISession; static Service g_apmISession;
static u64 g_refCnt;
static Result _apmGetSession(Service* srv, Service* srv_out, u64 cmd_id); static Result _apmGetSession(Service* srv, Service* srv_out, u64 cmd_id);
Result apmInitialize(void) Result apmInitialize(void)
{ {
atomicIncrement64(&g_refCnt);
if (serviceIsActive(&g_apmSrv)) if (serviceIsActive(&g_apmSrv))
return MAKERESULT(Module_Libnx, LibnxError_AlreadyInitialized); return 0;
Result rc = 0; Result rc = 0;
@ -34,8 +38,10 @@ Result apmInitialize(void)
void apmExit(void) void apmExit(void)
{ {
serviceClose(&g_apmISession); if (atomicDecrement64(&g_refCnt) == 0) {
serviceClose(&g_apmSrv); serviceClose(&g_apmISession);
serviceClose(&g_apmSrv);
}
} }
static Result _apmGetSession(Service* srv, Service* srv_out, u64 cmd_id) { static Result _apmGetSession(Service* srv, Service* srv_out, u64 cmd_id) {

View File

@ -1,12 +1,13 @@
#include <string.h> #include <string.h>
#include "types.h" #include "types.h"
#include "result.h" #include "result.h"
#include "arm/atomics.h"
#include "kernel/ipc.h" #include "kernel/ipc.h"
#include "kernel/detect.h"
#include "services/fatal.h" #include "services/fatal.h"
#include "services/applet.h" #include "services/applet.h"
#include "services/apm.h" #include "services/apm.h"
#include "services/sm.h" #include "services/sm.h"
#include "kernel/detect.h"
__attribute__((weak)) u32 __nx_applet_type = AppletType_Default; __attribute__((weak)) u32 __nx_applet_type = AppletType_Default;
__attribute__((weak)) bool __nx_applet_auto_notifyrunning = true; __attribute__((weak)) bool __nx_applet_auto_notifyrunning = true;
@ -15,6 +16,7 @@ __attribute__((weak)) u32 __nx_applet_PerformanceConfiguration[2] = {/*0x9222000
static Service g_appletSrv; static Service g_appletSrv;
static Service g_appletProxySession; static Service g_appletProxySession;
static u64 g_refCnt;
// From Get*Functions. // From Get*Functions.
static Service g_appletIFunctions; static Service g_appletIFunctions;
@ -69,8 +71,10 @@ static Result _appletSetPerformanceModeChangedNotification(u8 flag);
Result appletInitialize(void) Result appletInitialize(void)
{ {
atomicIncrement64(&g_refCnt);
if (serviceIsActive(&g_appletSrv)) if (serviceIsActive(&g_appletSrv))
return MAKERESULT(Module_Libnx, LibnxError_AlreadyInitialized); return 0;
if (__nx_applet_type == AppletType_None) if (__nx_applet_type == AppletType_None)
return 0; return 0;
@ -234,36 +238,39 @@ Result appletInitialize(void)
void appletExit(void) void appletExit(void)
{ {
apmExit(); if (atomicDecrement64(&g_refCnt) == 0)
{
apmExit();
//TODO: Enable this somehow later with more condition(s)? //TODO: Enable this somehow later with more condition(s)?
/*if (__nx_applet_type == AppletType_LibraryApplet) /*if (__nx_applet_type == AppletType_LibraryApplet)
_appletExitProcessAndReturn();*/ _appletExitProcessAndReturn();*/
if (g_appletMessageEventHandle != INVALID_HANDLE) { if (g_appletMessageEventHandle != INVALID_HANDLE) {
svcCloseHandle(g_appletMessageEventHandle); svcCloseHandle(g_appletMessageEventHandle);
g_appletMessageEventHandle = INVALID_HANDLE; g_appletMessageEventHandle = INVALID_HANDLE;
}
serviceClose(&g_appletIDebugFunctions);
serviceClose(&g_appletIDisplayController);
serviceClose(&g_appletIAudioController);
serviceClose(&g_appletIWindowController);
serviceClose(&g_appletISelfController);
serviceClose(&g_appletICommonStateGetter);
serviceClose(&g_appletILibraryAppletCreator);
if (__nx_applet_type != AppletType_LibraryApplet)
serviceClose(&g_appletIFunctions);
if (__nx_applet_type == AppletType_LibraryApplet) {
serviceClose(&g_appletIProcessWindingController);
serviceClose(&g_appletILibraryAppletSelfAccessor);
}
serviceClose(&g_appletProxySession);
serviceClose(&g_appletSrv);
g_appletResourceUserId = 0;
} }
serviceClose(&g_appletIDebugFunctions);
serviceClose(&g_appletIDisplayController);
serviceClose(&g_appletIAudioController);
serviceClose(&g_appletIWindowController);
serviceClose(&g_appletISelfController);
serviceClose(&g_appletICommonStateGetter);
serviceClose(&g_appletILibraryAppletCreator);
if (__nx_applet_type != AppletType_LibraryApplet)
serviceClose(&g_appletIFunctions);
if (__nx_applet_type == AppletType_LibraryApplet) {
serviceClose(&g_appletIProcessWindingController);
serviceClose(&g_appletILibraryAppletSelfAccessor);
}
serviceClose(&g_appletProxySession);
serviceClose(&g_appletSrv);
g_appletResourceUserId = 0;
} }
static void appletCallHook(AppletHookType hookType) static void appletCallHook(AppletHookType hookType)

View File

@ -1,6 +1,7 @@
#include <string.h> #include <string.h>
#include "types.h" #include "types.h"
#include "result.h" #include "result.h"
#include "arm/atomics.h"
#include "kernel/ipc.h" #include "kernel/ipc.h"
#include "services/audin.h" #include "services/audin.h"
#include "services/sm.h" #include "services/sm.h"
@ -11,6 +12,7 @@
static Service g_audinSrv; static Service g_audinSrv;
static Service g_audinIAudioIn; static Service g_audinIAudioIn;
static u64 g_refCnt;
static Handle g_audinBufferEventHandle = INVALID_HANDLE; static Handle g_audinBufferEventHandle = INVALID_HANDLE;
@ -23,8 +25,10 @@ static Result _audinRegisterBufferEvent(Handle *BufferEvent);
Result audinInitialize(void) Result audinInitialize(void)
{ {
atomicIncrement64(&g_refCnt);
if (serviceIsActive(&g_audinSrv)) if (serviceIsActive(&g_audinSrv))
return MAKERESULT(Module_Libnx, LibnxError_AlreadyInitialized); return 0;
Result rc = 0; Result rc = 0;
rc = smGetService(&g_audinSrv, "audin:u"); rc = smGetService(&g_audinSrv, "audin:u");
@ -52,18 +56,21 @@ Result audinInitialize(void)
void audinExit(void) void audinExit(void)
{ {
if (g_audinBufferEventHandle != INVALID_HANDLE) { if (atomicDecrement64(&g_refCnt) == 0)
svcCloseHandle(g_audinBufferEventHandle); {
g_audinBufferEventHandle = INVALID_HANDLE; if (g_audinBufferEventHandle != INVALID_HANDLE) {
svcCloseHandle(g_audinBufferEventHandle);
g_audinBufferEventHandle = INVALID_HANDLE;
}
g_sampleRate = 0;
g_channelCount = 0;
g_pcmFormat = PcmFormat_Invalid;
g_deviceState = AudioInState_Stopped;
serviceClose(&g_audinIAudioIn);
serviceClose(&g_audinSrv);
} }
g_sampleRate = 0;
g_channelCount = 0;
g_pcmFormat = PcmFormat_Invalid;
g_deviceState = AudioInState_Stopped;
serviceClose(&g_audinIAudioIn);
serviceClose(&g_audinSrv);
} }
u32 audinGetSampleRate(void) { u32 audinGetSampleRate(void) {

View File

@ -1,6 +1,7 @@
#include <string.h> #include <string.h>
#include "types.h" #include "types.h"
#include "result.h" #include "result.h"
#include "arm/atomics.h"
#include "kernel/ipc.h" #include "kernel/ipc.h"
#include "services/audout.h" #include "services/audout.h"
#include "services/sm.h" #include "services/sm.h"
@ -11,6 +12,7 @@
static Service g_audoutSrv; static Service g_audoutSrv;
static Service g_audoutIAudioOut; static Service g_audoutIAudioOut;
static u64 g_refCnt;
static Handle g_audoutBufferEventHandle = INVALID_HANDLE; static Handle g_audoutBufferEventHandle = INVALID_HANDLE;
@ -23,8 +25,10 @@ static Result _audoutRegisterBufferEvent(Handle *BufferEvent);
Result audoutInitialize(void) Result audoutInitialize(void)
{ {
atomicIncrement64(&g_refCnt);
if (serviceIsActive(&g_audoutSrv)) if (serviceIsActive(&g_audoutSrv))
return MAKERESULT(Module_Libnx, LibnxError_AlreadyInitialized); return 0;
Result rc = 0; Result rc = 0;
rc = smGetService(&g_audoutSrv, "audout:u"); rc = smGetService(&g_audoutSrv, "audout:u");
@ -52,18 +56,21 @@ Result audoutInitialize(void)
void audoutExit(void) void audoutExit(void)
{ {
if (g_audoutBufferEventHandle != INVALID_HANDLE) { if (atomicDecrement64(&g_refCnt) == 0)
svcCloseHandle(g_audoutBufferEventHandle); {
g_audoutBufferEventHandle = INVALID_HANDLE; if (g_audoutBufferEventHandle != INVALID_HANDLE) {
svcCloseHandle(g_audoutBufferEventHandle);
g_audoutBufferEventHandle = INVALID_HANDLE;
}
g_sampleRate = 0;
g_channelCount = 0;
g_pcmFormat = PcmFormat_Invalid;
g_deviceState = AudioOutState_Stopped;
serviceClose(&g_audoutIAudioOut);
serviceClose(&g_audoutSrv);
} }
g_sampleRate = 0;
g_channelCount = 0;
g_pcmFormat = PcmFormat_Invalid;
g_deviceState = AudioOutState_Stopped;
serviceClose(&g_audoutIAudioOut);
serviceClose(&g_audoutSrv);
} }
u32 audoutGetSampleRate(void) { u32 audoutGetSampleRate(void) {

View File

@ -2,13 +2,18 @@
#include <string.h> #include <string.h>
#include "types.h" #include "types.h"
#include "result.h" #include "result.h"
#include "arm/atomics.h"
#include "kernel/ipc.h" #include "kernel/ipc.h"
#include "services/fs.h" #include "services/fs.h"
#include "services/sm.h" #include "services/sm.h"
static Service g_fsSrv; static Service g_fsSrv;
static u64 g_refCnt;
Result fsInitialize(void)
{
atomicIncrement64(&g_refCnt);
Result fsInitialize(void) {
if (serviceIsActive(&g_fsSrv)) if (serviceIsActive(&g_fsSrv))
return 0; return 0;
@ -49,8 +54,10 @@ Result fsInitialize(void) {
return rc; return rc;
} }
void fsExit(void) { void fsExit(void)
serviceClose(&g_fsSrv); {
if (atomicDecrement64(&g_refCnt) == 0)
serviceClose(&g_fsSrv);
} }
Service* fsGetServiceSession(void) { Service* fsGetServiceSession(void) {

View File

@ -1,15 +1,17 @@
#include <string.h> #include <string.h>
#include "types.h" #include "types.h"
#include "result.h" #include "result.h"
#include "arm/atomics.h"
#include "kernel/ipc.h" #include "kernel/ipc.h"
#include "kernel/shmem.h"
#include "kernel/rwlock.h"
#include "services/applet.h" #include "services/applet.h"
#include "services/hid.h" #include "services/hid.h"
#include "services/sm.h" #include "services/sm.h"
#include "kernel/shmem.h"
#include "kernel/rwlock.h"
static Service g_hidSrv; static Service g_hidSrv;
static Service g_hidIAppletResource; static Service g_hidIAppletResource;
static u64 g_refCnt;
static SharedMemory g_hidSharedmem; static SharedMemory g_hidSharedmem;
static HidTouchScreenEntry g_touchEntry; static HidTouchScreenEntry g_touchEntry;
@ -36,8 +38,10 @@ static Result _hidSetDualModeAll(void);
Result hidInitialize(void) Result hidInitialize(void)
{ {
atomicIncrement64(&g_refCnt);
if (serviceIsActive(&g_hidSrv)) if (serviceIsActive(&g_hidSrv))
return MAKERESULT(Module_Libnx, LibnxError_AlreadyInitialized); return 0;
Result rc; Result rc;
Handle sharedmem_handle; Handle sharedmem_handle;
@ -75,14 +79,14 @@ Result hidInitialize(void)
void hidExit(void) void hidExit(void)
{ {
if (!serviceIsActive(&g_hidSrv)) if (atomicDecrement64(&g_refCnt) == 0)
return; {
_hidSetDualModeAll();
_hidSetDualModeAll(); serviceClose(&g_hidIAppletResource);
serviceClose(&g_hidSrv);
serviceClose(&g_hidIAppletResource); shmemClose(&g_hidSharedmem);
serviceClose(&g_hidSrv); }
shmemClose(&g_hidSharedmem);
} }
void hidReset(void) void hidReset(void)
@ -367,7 +371,7 @@ void hidJoystickRead(JoystickPosition *pos, HidControllerID id, HidControllerJoy
} }
static Result _hidSetDualModeAll(void) { static Result _hidSetDualModeAll(void) {
Result rc=0; Result rc;
int i; int i;
for (i=0; i<8; i++) { for (i=0; i<8; i++) {

View File

@ -1,6 +1,7 @@
#include <string.h> #include <string.h>
#include "types.h" #include "types.h"
#include "result.h" #include "result.h"
#include "arm/atomics.h"
#include "kernel/ipc.h" #include "kernel/ipc.h"
#include "kernel/shmem.h" #include "kernel/shmem.h"
#include "kernel/tmem.h" #include "kernel/tmem.h"
@ -16,6 +17,7 @@ typedef struct {
} irsCameraEntry; } irsCameraEntry;
static Service g_irsSrv; static Service g_irsSrv;
static u64 g_refCnt;
static SharedMemory g_irsSharedmem; static SharedMemory g_irsSharedmem;
static bool g_irsSensorActivated; static bool g_irsSensorActivated;
@ -25,8 +27,10 @@ static Result _irsGetIrsensorSharedMemoryHandle(Handle* handle_out, u64 AppletRe
Result irsInitialize(void) Result irsInitialize(void)
{ {
atomicIncrement64(&g_refCnt);
if (serviceIsActive(&g_irsSrv)) if (serviceIsActive(&g_irsSrv))
return MAKERESULT(Module_Libnx, LibnxError_AlreadyInitialized); return 0;
Result rc; Result rc;
Handle sharedmem_handle; Handle sharedmem_handle;
@ -60,20 +64,23 @@ Result irsInitialize(void)
void irsExit(void) void irsExit(void)
{ {
int i; if (atomicDecrement64(&g_refCnt) == 0)
size_t entrycount = sizeof(g_irsCameras)/sizeof(irsCameraEntry); {
irsCameraEntry *entry; size_t entrycount = sizeof(g_irsCameras)/sizeof(irsCameraEntry);
irsCameraEntry *entry;
for(i=0; i<entrycount; i++) { int i;
entry = &g_irsCameras[i]; for(i=0; i<entrycount; i++) {
if (!entry->initialized) continue; entry = &g_irsCameras[i];
irsStopImageProcessor(entry->IrCameraHandle); if (!entry->initialized) continue;
irsStopImageProcessor(entry->IrCameraHandle);
}
irsActivateIrsensor(0);
serviceClose(&g_irsSrv);
shmemClose(&g_irsSharedmem);
} }
irsActivateIrsensor(0);
serviceClose(&g_irsSrv);
shmemClose(&g_irsSharedmem);
} }
static Result _irsCameraEntryAlloc(u32 IrCameraHandle, irsCameraEntry **out_entry) { static Result _irsCameraEntryAlloc(u32 IrCameraHandle, irsCameraEntry **out_entry) {

View File

@ -18,7 +18,7 @@ static Result _nvSetClientPID(u64 AppletResourceUserId);
Result nvInitialize(nvServiceType servicetype, size_t transfermem_size) Result nvInitialize(nvServiceType servicetype, size_t transfermem_size)
{ {
if(g_nvServiceType!=-1) if (g_nvServiceType != -1)
return MAKERESULT(Module_Libnx, LibnxError_AlreadyInitialized); return MAKERESULT(Module_Libnx, LibnxError_AlreadyInitialized);
Result rc = 0; Result rc = 0;
@ -70,7 +70,7 @@ Result nvInitialize(nvServiceType servicetype, size_t transfermem_size)
void nvExit(void) void nvExit(void)
{ {
if(g_nvServiceType == -1) if (g_nvServiceType == -1)
return; return;
g_nvServiceType = -1; g_nvServiceType = -1;

View File

@ -1,16 +1,31 @@
// Copyright 2017 plutoo // Copyright 2017 plutoo
#include "types.h" #include "types.h"
#include "result.h" #include "result.h"
#include "arm/atomics.h"
#include "kernel/ipc.h" #include "kernel/ipc.h"
#include "services/pm.h" #include "services/pm.h"
#include "services/sm.h" #include "services/sm.h"
static Service g_pmdmntSrv; static Service g_pmdmntSrv;
static u64 g_refCnt;
Result pmdmntInitialize(void)
{
atomicIncrement64(&g_refCnt);
if (serviceIsActive(&g_pmdmntSrv))
return 0;
Result pmdmntInitialize(void) {
return smGetService(&g_pmdmntSrv, "pm:dmnt"); return smGetService(&g_pmdmntSrv, "pm:dmnt");
} }
void pmdmntExit(void)
{
if (atomicDecrement64(&g_refCnt) == 0) {
serviceClose(&g_pmdmntSrv);
}
}
Result pmdmntStartProcess(u64 pid) { Result pmdmntStartProcess(u64 pid) {
IpcCommand c; IpcCommand c;
ipcInitialize(&c); ipcInitialize(&c);

View File

@ -7,6 +7,7 @@
*/ */
#include "types.h" #include "types.h"
#include "result.h" #include "result.h"
#include "arm/atomics.h"
#include "kernel/ipc.h" #include "kernel/ipc.h"
#include "kernel/detect.h" #include "kernel/detect.h"
#include "services/set.h" #include "services/set.h"
@ -15,6 +16,8 @@
static Service g_setSrv; static Service g_setSrv;
static Service g_setsysSrv; static Service g_setsysSrv;
static u64 g_refCnt;
static u64 g_refCntSys;
static bool g_setLanguageCodesInitialized; static bool g_setLanguageCodesInitialized;
static u64 g_setLanguageCodes[0x40]; static u64 g_setLanguageCodes[0x40];
@ -24,8 +27,10 @@ static Result _setMakeLanguageCode(s32 Language, u64 *LanguageCode);
Result setInitialize(void) Result setInitialize(void)
{ {
atomicIncrement64(&g_refCnt);
if (serviceIsActive(&g_setSrv)) if (serviceIsActive(&g_setSrv))
return MAKERESULT(Module_Libnx, LibnxError_AlreadyInitialized); return 0;
g_setLanguageCodesInitialized = 0; g_setLanguageCodesInitialized = 0;
@ -34,11 +39,15 @@ Result setInitialize(void)
void setExit(void) void setExit(void)
{ {
serviceClose(&g_setSrv); if (atomicDecrement64(&g_refCnt) == 0) {
serviceClose(&g_setSrv);
}
} }
Result setsysInitialize(void) Result setsysInitialize(void)
{ {
atomicIncrement64(&g_refCntSys);
if (serviceIsActive(&g_setsysSrv)) if (serviceIsActive(&g_setsysSrv))
return MAKERESULT(Module_Libnx, LibnxError_AlreadyInitialized); return MAKERESULT(Module_Libnx, LibnxError_AlreadyInitialized);
@ -47,7 +56,9 @@ Result setsysInitialize(void)
void setsysExit(void) void setsysExit(void)
{ {
serviceClose(&g_setsysSrv); if (atomicDecrement64(&g_refCntSys) == 0) {
serviceClose(&g_setsysSrv);
}
} }
static Result setInitializeLanguageCodesCache(void) { static Result setInitializeLanguageCodesCache(void) {

View File

@ -1,11 +1,13 @@
// Copyright 2017 plutoo // Copyright 2017 plutoo
#include "types.h" #include "types.h"
#include "result.h" #include "result.h"
#include "arm/atomics.h"
#include "kernel/ipc.h" #include "kernel/ipc.h"
#include "services/fatal.h" #include "services/fatal.h"
#include "services/sm.h" #include "services/sm.h"
static Handle g_smHandle = INVALID_HANDLE; static Handle g_smHandle = INVALID_HANDLE;
static u64 g_refCnt;
#define MAX_OVERRIDES 32 #define MAX_OVERRIDES 32
@ -48,6 +50,8 @@ bool smHasInitialized(void) {
Result smInitialize(void) Result smInitialize(void)
{ {
atomicIncrement64(&g_refCnt);
if (smHasInitialized()) if (smHasInitialized())
return 0; return 0;
@ -93,9 +97,12 @@ Result smInitialize(void)
return rc; return rc;
} }
void smExit(void) { void smExit(void)
svcCloseHandle(g_smHandle); {
g_smHandle = INVALID_HANDLE; if (atomicDecrement64(&g_refCnt) == 0) {
svcCloseHandle(g_smHandle);
g_smHandle = INVALID_HANDLE;
}
} }
u64 smEncodeName(const char* name) u64 smEncodeName(const char* name)

View File

@ -1,6 +1,7 @@
#include <string.h> #include <string.h>
#include "types.h" #include "types.h"
#include "result.h" #include "result.h"
#include "arm/atomics.h"
#include "kernel/ipc.h" #include "kernel/ipc.h"
#include "services/time.h" #include "services/time.h"
#include "services/sm.h" #include "services/sm.h"
@ -10,13 +11,16 @@ static Service g_timeUserSystemClock;
static Service g_timeNetworkSystemClock; static Service g_timeNetworkSystemClock;
static Service g_timeTimeZoneService; static Service g_timeTimeZoneService;
static Service g_timeLocalSystemClock; static Service g_timeLocalSystemClock;
static u64 g_refCnt;
static Result _timeGetSession(Service* srv_out, u64 cmd_id); static Result _timeGetSession(Service* srv_out, u64 cmd_id);
Result timeInitialize(void) Result timeInitialize(void)
{ {
atomicIncrement64(&g_refCnt);
if (serviceIsActive(&g_timeSrv)) if (serviceIsActive(&g_timeSrv))
return MAKERESULT(Module_Libnx, LibnxError_AlreadyInitialized); return 0;
Result rc; Result rc;
@ -46,14 +50,14 @@ Result timeInitialize(void)
void timeExit(void) void timeExit(void)
{ {
if (!serviceIsActive(&g_timeSrv)) if (atomicDecrement64(&g_refCnt) == 0)
return; {
serviceClose(&g_timeLocalSystemClock);
serviceClose(&g_timeLocalSystemClock); serviceClose(&g_timeTimeZoneService);
serviceClose(&g_timeTimeZoneService); serviceClose(&g_timeNetworkSystemClock);
serviceClose(&g_timeNetworkSystemClock); serviceClose(&g_timeUserSystemClock);
serviceClose(&g_timeUserSystemClock); serviceClose(&g_timeSrv);
serviceClose(&g_timeSrv); }
} }
Service* timeGetSessionService(void) { Service* timeGetSessionService(void) {

View File

@ -25,7 +25,8 @@ static Result _usbDsSetVidPidBcd(const usbDsDeviceInfo* deviceinfo);
static Result _usbDsGetSession(Service* srv, Service* srv_out, u64 cmd_id, const void* buf0, size_t buf0size, const void* buf1, size_t buf1size); static Result _usbDsGetSession(Service* srv, Service* srv_out, u64 cmd_id, const void* buf0, size_t buf0size, const void* buf1, size_t buf1size);
Result usbDsInitialize(UsbComplexId complexId, const usbDsDeviceInfo* deviceinfo) { Result usbDsInitialize(UsbComplexId complexId, const usbDsDeviceInfo* deviceinfo)
{
if (serviceIsActive(&g_usbDsSrv)) if (serviceIsActive(&g_usbDsSrv))
return MAKERESULT(Module_Libnx, LibnxError_AlreadyInitialized); return MAKERESULT(Module_Libnx, LibnxError_AlreadyInitialized);