Created
June 8, 2018 22:40
-
-
Save SonoSooS/636257a7621791ab522455733152e4f8 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#hdr | |
#include <3ds.h> | |
#end | |
#src | |
#include "stdmacro.h" | |
#end | |
typedef void (*SignalHandler)(u32 notif); | |
struct SignalHook | |
{ | |
u32 notificaton; | |
SignalHandler func; | |
SignalHook* next; | |
}; | |
class srv | |
{ | |
public: | |
static Handle notifsemaphore = 0; | |
static RecursiveLock rlock; | |
static int count = 0; | |
static SignalHook sigroot; | |
static vu8 running = 0; | |
static Thread thread = 0; | |
static Result init() | |
{ | |
if(AtomicPostIncrement(&count)) return 0; | |
Result res = srvInit(); | |
if(res < 0) goto fail; | |
RecursiveLock_Init(&rlock); | |
sigroot.notificaton = 0; | |
sigroot.func = nullptr; | |
sigroot.next = nullptr; | |
srvEnableNotification(¬ifsemaphore); | |
srv::running = 1; | |
thread = threadCreate(handlerloop, nullptr, 0x2000, 0x31, -2, true); | |
if(!thread) err(56, 0xF00FCACE); | |
return 0; | |
fail: | |
AtomicDecrement(&count); | |
return res; | |
} | |
static void exit() | |
{ | |
if(AtomicDecrement(&count)) return; | |
running = 0; | |
lock(); | |
SignalHook* curr = sigroot.next; | |
SignalHook* temp = nullptr; | |
while(curr) | |
{ | |
temp = curr->next; | |
delete curr; | |
curr = temp; | |
} | |
sigroot.notificaton = 0; | |
sigroot.func = nullptr; | |
sigroot.next = nullptr; | |
unlock(); | |
srvExit(); | |
} | |
static void lock() | |
{ | |
RecursiveLock_Lock(&rlock); | |
} | |
static void unlock() | |
{ | |
RecursiveLock_Unlock(&rlock); | |
} | |
static void handlerloop(void* param) | |
{ | |
Result ret = 0; | |
u32 NotificationID = 0; | |
while(running) | |
{ | |
ret = svcWaitSynchronization(notifsemaphore, -1ULL); | |
if(!running) break; | |
if(ret < 0) break; | |
lock(); | |
ret = srvReceiveNotification(&NotificationID); | |
if(ret < 0) | |
{ | |
unlock(); | |
break; | |
} | |
SignalHook* curr = &sigroot; | |
while(curr) | |
{ | |
if(curr->func && (!curr->notificaton || curr->notificaton == NotificationID)) curr->func(NotificationID); | |
curr = curr->next; | |
} | |
unlock(); | |
} | |
svcCloseHandle(notifsemaphore); | |
if(running) *(u32*)0x00100666 = ret; | |
} | |
static void hook(u32 notifid, SignalHandler func) | |
{ | |
if(!func) return; | |
SignalHook* curr = &sigroot; | |
if(sigroot.func) | |
{ | |
while(curr->next) | |
{ | |
curr = curr->next; | |
} | |
curr->next = new SignalHook; | |
curr = curr->next; | |
curr->next = nullptr; | |
} | |
curr->notificaton = notifid; | |
curr->func = func; | |
srvSubscribe(notifid); | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment