Software / code / prosody
Comparison
util-src/signal.c @ 8414:7ea3311ca632
util.signal: Use a static array to keep track of pending signals (fixes #1029)
| author | Kim Alvefur <zash@zash.se> |
|---|---|
| date | Tue, 14 Nov 2017 15:20:14 +0100 |
| parent | 7973:703f7f45feb4 |
| child | 8420:fb27aff6d491 |
comparison
equal
deleted
inserted
replaced
| 8411:a9e8523a5e73 | 8414:7ea3311ca632 |
|---|---|
| 47 int sig; /* the signal */ | 47 int sig; /* the signal */ |
| 48 }; | 48 }; |
| 49 | 49 |
| 50 #endif | 50 #endif |
| 51 | 51 |
| 52 #define MAX_PENDING_SIGNALS 32 | |
| 53 | |
| 52 #define LUA_SIGNAL "lua_signal" | 54 #define LUA_SIGNAL "lua_signal" |
| 53 | 55 |
| 54 static const struct lua_signal lua_signals[] = { | 56 static const struct lua_signal lua_signals[] = { |
| 55 /* ANSI C signals */ | 57 /* ANSI C signals */ |
| 56 #ifdef SIGABRT | 58 #ifdef SIGABRT |
| 158 static lua_State *Lsig = NULL; | 160 static lua_State *Lsig = NULL; |
| 159 static lua_Hook Hsig = NULL; | 161 static lua_Hook Hsig = NULL; |
| 160 static int Hmask = 0; | 162 static int Hmask = 0; |
| 161 static int Hcount = 0; | 163 static int Hcount = 0; |
| 162 | 164 |
| 163 static struct signal_event { | 165 int signals[MAX_PENDING_SIGNALS]; |
| 164 int Nsig; | 166 int nsig = 0; |
| 165 struct signal_event *next_event; | |
| 166 } *signal_queue = NULL; | |
| 167 | |
| 168 static struct signal_event *last_event = NULL; | |
| 169 | 167 |
| 170 static void sighook(lua_State *L, lua_Debug *ar) { | 168 static void sighook(lua_State *L, lua_Debug *ar) { |
| 171 struct signal_event *event; | |
| 172 /* restore the old hook */ | 169 /* restore the old hook */ |
| 173 lua_sethook(L, Hsig, Hmask, Hcount); | 170 lua_sethook(L, Hsig, Hmask, Hcount); |
| 174 | 171 |
| 175 lua_pushstring(L, LUA_SIGNAL); | 172 lua_pushstring(L, LUA_SIGNAL); |
| 176 lua_gettable(L, LUA_REGISTRYINDEX); | 173 lua_gettable(L, LUA_REGISTRYINDEX); |
| 177 | 174 |
| 178 while((event = signal_queue)) { | 175 for(int i = 1; i <= nsig; i--) { |
| 179 lua_pushnumber(L, event->Nsig); | 176 lua_pushnumber(L, signals[i]); |
| 180 lua_gettable(L, -2); | 177 lua_gettable(L, -2); |
| 181 lua_call(L, 0, 0); | 178 lua_call(L, 0, 0); |
| 182 signal_queue = event->next_event; | |
| 183 free(event); | |
| 184 }; | 179 }; |
| 185 | 180 |
| 181 nsig = 0; | |
| 182 | |
| 186 lua_pop(L, 1); /* pop lua_signal table */ | 183 lua_pop(L, 1); /* pop lua_signal table */ |
| 187 | 184 |
| 188 } | 185 } |
| 189 | 186 |
| 190 static void handle(int sig) { | 187 static void handle(int sig) { |
| 191 if(!signal_queue) { | 188 if(nsig == 0) { |
| 192 /* Store the existing debug hook (if any) and its parameters */ | 189 /* Store the existing debug hook (if any) and its parameters */ |
| 193 Hsig = lua_gethook(Lsig); | 190 Hsig = lua_gethook(Lsig); |
| 194 Hmask = lua_gethookmask(Lsig); | 191 Hmask = lua_gethookmask(Lsig); |
| 195 Hcount = lua_gethookcount(Lsig); | 192 Hcount = lua_gethookcount(Lsig); |
| 196 | 193 |
| 197 signal_queue = malloc(sizeof(struct signal_event)); | |
| 198 signal_queue->Nsig = sig; | |
| 199 signal_queue->next_event = NULL; | |
| 200 | |
| 201 last_event = signal_queue; | |
| 202 | |
| 203 /* Set our new debug hook */ | 194 /* Set our new debug hook */ |
| 204 lua_sethook(Lsig, sighook, LUA_MASKCALL | LUA_MASKRET | LUA_MASKCOUNT, 1); | 195 lua_sethook(Lsig, sighook, LUA_MASKCALL | LUA_MASKRET | LUA_MASKCOUNT, 1); |
| 205 } else { | 196 } |
| 206 last_event->next_event = malloc(sizeof(struct signal_event)); | 197 |
| 207 last_event->next_event->Nsig = sig; | 198 if(nsig < MAX_PENDING_SIGNALS) { |
| 208 last_event->next_event->next_event = NULL; | 199 signals[++nsig] = sig; |
| 209 | |
| 210 last_event = last_event->next_event; | |
| 211 } | 200 } |
| 212 } | 201 } |
| 213 | 202 |
| 214 /* | 203 /* |
| 215 * l_signal == signal(signal [, func [, chook]]) | 204 * l_signal == signal(signal [, func [, chook]]) |