aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Wild <mwild1@gmail.com>2010-01-10 00:28:48 +0000
committerMatthew Wild <mwild1@gmail.com>2010-01-10 00:28:48 +0000
commit96c4c4f090617ead071487dce924517cd281b7a6 (patch)
tree47cbae773978e0bdd6f4f844f5aaffcd6aab646b
parent0ac9242e025f4d799b5645957f72547eff06f77f (diff)
downloadprosody-96c4c4f090617ead071487dce924517cd281b7a6.tar.gz
prosody-96c4c4f090617ead071487dce924517cd281b7a6.zip
util.signal: Queue up multiple signals, instead of trampling on the previous debug hook (and never clearing our own)
-rw-r--r--util-src/lsignal.c64
1 files changed, 44 insertions, 20 deletions
diff --git a/util-src/lsignal.c b/util-src/lsignal.c
index 30975508..e4dffa02 100644
--- a/util-src/lsignal.c
+++ b/util-src/lsignal.c
@@ -27,6 +27,7 @@
*/
#include <signal.h>
+#include <malloc.h>
#include "lua.h"
#include "lauxlib.h"
@@ -149,43 +150,66 @@ static const struct lua_signal lua_signals[] = {
{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;
-
- lua_sethook(Lsig, sighook, LUA_MASKCALL | LUA_MASKRET | LUA_MASKCOUNT, 1);
- /*
- switch (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;
+
+ 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;
+ }
}
/*