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 | ca9c6121a2a2bf399c6be62a1809712d6064919c (patch) | |
tree | ba68face402ceedc72f6da18fe45e8fea0d9e163 /util-src | |
parent | e9bd8209bba36616a42269c78cfd14dd53c49fa0 (diff) | |
download | prosody-ca9c6121a2a2bf399c6be62a1809712d6064919c.tar.gz prosody-ca9c6121a2a2bf399c6be62a1809712d6064919c.zip |
util.signal: Queue up multiple signals, instead of trampling on the previous debug hook (and never clearing our own)
Diffstat (limited to 'util-src')
-rw-r--r-- | util-src/signal.c | 64 |
1 files changed, 44 insertions, 20 deletions
diff --git a/util-src/signal.c b/util-src/signal.c index 447c1c16..4bda69d8 100644 --- a/util-src/signal.c +++ b/util-src/signal.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; + } } /* |