]> jfr.im git - irc/quakenet/newserv.git/blobdiff - core/hooks.c
merge
[irc/quakenet/newserv.git] / core / hooks.c
index b79aa240f600bf352596c12ca288cbbf361e0028..8a78e3c0dd9caa5ff26009e6af16d0c57fc3e8e4 100644 (file)
@@ -3,12 +3,15 @@
 #include "hooks.h"
 #include <assert.h>
 #include "../lib/array.h"
+#include <stdlib.h>
 
 array hooks[HOOKMAX];
+unsigned int hookqueuelength;
 
 void inithooks() {
   int i;
   
+  hookqueuelength=0;
   for (i=0;i<HOOKMAX;i++) {
     array_init(&(hooks[i]),sizeof(HookCallback));
     array_setlim1(&(hooks[i]),2);
@@ -28,6 +31,14 @@ int registerhook(int hooknum, HookCallback callback) {
     if(hcbs[i]==callback)
       return 1;
 
+  /* If there is a previously blanked slot, go in there */
+  for(i=0;i<hooks[hooknum].cursi;i++) {
+    if(hcbs[i]==NULL) {
+      hcbs[i]=callback;
+      return 0;
+    }
+  }
+
   i=array_getfreeslot(&hooks[hooknum]);
   hcbs=(HookCallback *)(hooks[hooknum].content);
   hcbs[i]=callback;
@@ -46,7 +57,13 @@ int deregisterhook(int hooknum, HookCallback callback) {
 
   for(i=0;i<hooks[hooknum].cursi;i++)
     if(hcbs[i]==callback) {
-      array_delslot(&(hooks[hooknum]),i);
+      /* If there is an ongoing callback, don't actually delete from the
+       * array in case THIS hook is active */
+      if (hookqueuelength) {
+        hcbs[i]=NULL;
+      } else {
+        array_delslot(&(hooks[hooknum]),i);
+      }
       return 0;
     }
 
@@ -60,9 +77,14 @@ void triggerhook(int hooknum, void *arg) {
   if (hooknum>HOOKMAX)
     return;
     
+  hookqueuelength++;
   hcbs=(HookCallback *)(hooks[hooknum].content);
   for (i=0;i<hooks[hooknum].cursi;i++) {
-    (hcbs[i])(hooknum, arg);
+    if (hcbs[i])
+      (hcbs[i])(hooknum, arg);
   }
-}
+  hookqueuelength--;
   
+  if (!hookqueuelength && hooknum!=HOOK_CORE_ENDOFHOOKSQUEUE)
+    triggerhook(HOOK_CORE_ENDOFHOOKSQUEUE, 0);
+}