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