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]]) |