Skip to content

Instantly share code, notes, and snippets.

@SonoSooS
Created June 8, 2018 22:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save SonoSooS/636257a7621791ab522455733152e4f8 to your computer and use it in GitHub Desktop.
Save SonoSooS/636257a7621791ab522455733152e4f8 to your computer and use it in GitHub Desktop.
#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(&notifsemaphore);
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