util.signal: Queue up multiple signals, instead of trampling on the previous debug hook (and never clearing our own)
authorMatthew Wild <mwild1@gmail.com>
Sun, 10 Jan 2010 00:28:48 +0000
changeset 2790 fa717c0be65c
parent 2789 2419ca0bfab3
child 2791 e23b642bdfd1
util.signal: Queue up multiple signals, instead of trampling on the previous debug hook (and never clearing our own)
util-src/lsignal.c
--- a/util-src/lsignal.c	Sat Jan 09 07:12:30 2010 +0000
+++ b/util-src/lsignal.c	Sun Jan 10 00:28:48 2010 +0000
@@ -27,6 +27,7 @@
 */
 
 #include <signal.h>
+#include <malloc.h>
 
 #include "lua.h"
 #include "lauxlib.h"
@@ -149,43 +150,66 @@
   {NULL, 0}
 };
 
-static int Nsig = 0;
 static lua_State *Lsig = NULL;
 static lua_Hook Hsig = NULL;
 static int Hmask = 0;
 static int Hcount = 0;
 
+static struct signal_event
+{
+	int Nsig;
+	struct signal_event *next_event;
+} *signal_queue = NULL;
+
+static struct signal_event *last_event = NULL;
+
 static void sighook(lua_State *L, lua_Debug *ar)
 {
   lua_pushstring(L, LUA_SIGNAL);
   lua_gettable(L, LUA_REGISTRYINDEX);
-  lua_pushnumber(L, Nsig);
-  lua_gettable(L, -2);
 
-  lua_call(L, 0, 0);
+  struct signal_event *event;
+  while((event = signal_queue))
+  {
+    lua_pushnumber(L, event->Nsig);
+    lua_gettable(L, -2);
+    lua_call(L, 0, 0);
+    signal_queue = event->next_event;
+    free(event);
+  };
 
-  /* set the old hook */
+  lua_pop(L, 1); /* pop lua_signal table */
+
+  /* restore the old hook */
   lua_sethook(L, Hsig, Hmask, Hcount);
 }
 
 static void handle(int sig)
 {
-  Hsig = lua_gethook(Lsig);
-  Hmask = lua_gethookmask(Lsig);
-  Hcount = lua_gethookcount(Lsig);
-  Nsig = sig;
+  if(!signal_queue)
+  {
+    /* Store the existing debug hook (if any) and its parameters */
+    Hsig = lua_gethook(Lsig);
+    Hmask = lua_gethookmask(Lsig);
+    Hcount = lua_gethookcount(Lsig);
+    
+    signal_queue = malloc(sizeof(struct signal_event));
+    signal_queue->Nsig = sig;
+    signal_queue->next_event = NULL;
 
-  lua_sethook(Lsig, sighook, LUA_MASKCALL | LUA_MASKRET | LUA_MASKCOUNT, 1);
-  /*
-  switch (sig)
+    last_event = signal_queue;
+    
+    /* Set our new debug hook */
+    lua_sethook(Lsig, sighook, LUA_MASKCALL | LUA_MASKRET | LUA_MASKCOUNT, 1);
+  }
+  else
   {
-    case SIGABRT: ;
-    case SIGFPE: ;
-    case SIGILL: ;
-    case SIGINT: ;
-    case SIGSEGV: ;
-    case SIGTERM: ;
-  } */
+    last_event->next_event = malloc(sizeof(struct signal_event));
+    last_event->next_event->Nsig = sig;
+    last_event->next_event->next_event = NULL;
+    
+    last_event = last_event->next_event;
+  }
 }
 
 /*