diff options
author | Matthew Wild <mwild1@gmail.com> | 2010-01-10 00:28:48 +0000 |
---|---|---|
committer | Matthew Wild <mwild1@gmail.com> | 2010-01-10 00:28:48 +0000 |
commit | 96c4c4f090617ead071487dce924517cd281b7a6 (patch) | |
tree | 47cbae773978e0bdd6f4f844f5aaffcd6aab646b | |
parent | 0ac9242e025f4d799b5645957f72547eff06f77f (diff) | |
download | prosody-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.c | 64 |
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; + } } /* |