diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2020-05-22 11:40:34 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2020-05-22 11:40:34 -0300 |
| commit | 17dbaa8639505c9ad1a9946591f5960123fbd741 (patch) | |
| tree | c078795bfb4a748ca05faabefafab4e35493714a | |
| parent | 9514abc2da3525ef4314a8fcf70982ad07319e51 (diff) | |
| download | lua-17dbaa8639505c9ad1a9946591f5960123fbd741.tar.gz lua-17dbaa8639505c9ad1a9946591f5960123fbd741.tar.bz2 lua-17dbaa8639505c9ad1a9946591f5960123fbd741.zip | |
Improvements in the handling of signals
Added 'volatile' to 'l_signalT' variables plus some minor changes.
| -rw-r--r-- | ldebug.c | 20 | ||||
| -rw-r--r-- | ldo.c | 10 | ||||
| -rw-r--r-- | lstate.c | 9 | ||||
| -rw-r--r-- | lstate.h | 4 | ||||
| -rw-r--r-- | lua.c | 3 |
5 files changed, 25 insertions, 21 deletions
| @@ -107,13 +107,15 @@ static int getcurrentline (CallInfo *ci) { | |||
| 107 | 107 | ||
| 108 | 108 | ||
| 109 | /* | 109 | /* |
| 110 | ** This function can be called asynchronously (e.g. during a signal), | 110 | ** Set 'trap' for all active Lua frames. |
| 111 | ** under "reasonable" assumptions. A new 'ci' is completely linked | 111 | ** This function can be called during a signal, under "reasonable" |
| 112 | ** in the list before it becomes part of the "active" list, and | 112 | ** assumptions. A new 'ci' is completely linked in the list before it |
| 113 | ** we assume that pointers are atomic (see comment in next function). | 113 | ** becomes part of the "active" list, and we assume that pointers are |
| 114 | ** (If we traverse one more item, there is no problem. If we traverse | 114 | ** atomic; see comment in next function. |
| 115 | ** one less item, the worst that can happen is that the signal will | 115 | ** (A compiler doing interprocedural optimizations could, theoretically, |
| 116 | ** not interrupt the script.) | 116 | ** reorder memory writes in such a way that the list could be |
| 117 | ** temporarily broken while inserting a new element. We simply assume it | ||
| 118 | ** has no good reasons to do that.) | ||
| 117 | */ | 119 | */ |
| 118 | static void settraps (CallInfo *ci) { | 120 | static void settraps (CallInfo *ci) { |
| 119 | for (; ci != NULL; ci = ci->previous) | 121 | for (; ci != NULL; ci = ci->previous) |
| @@ -123,8 +125,8 @@ static void settraps (CallInfo *ci) { | |||
| 123 | 125 | ||
| 124 | 126 | ||
| 125 | /* | 127 | /* |
| 126 | ** This function can be called asynchronously (e.g. during a signal), | 128 | ** This function can be called during a signal, under "reasonable" |
| 127 | ** under "reasonable" assumptions. | 129 | ** assumptions. |
| 128 | ** Fields 'oldpc', 'basehookcount', and 'hookcount' (set by | 130 | ** Fields 'oldpc', 'basehookcount', and 'hookcount' (set by |
| 129 | ** 'resethookcount') are for debug only, and it is no problem if they | 131 | ** 'resethookcount') are for debug only, and it is no problem if they |
| 130 | ** get arbitrary values (causes at most one wrong hook call). 'hookmask' | 132 | ** get arbitrary values (causes at most one wrong hook call). 'hookmask' |
| @@ -422,7 +422,7 @@ void luaD_poscall (lua_State *L, CallInfo *ci, int nres) { | |||
| 422 | 422 | ||
| 423 | 423 | ||
| 424 | 424 | ||
| 425 | #define next_ci(L) (L->ci = (L->ci->next ? L->ci->next : luaE_extendCI(L))) | 425 | #define next_ci(L) (L->ci->next ? L->ci->next : luaE_extendCI(L)) |
| 426 | 426 | ||
| 427 | 427 | ||
| 428 | /* | 428 | /* |
| @@ -466,13 +466,13 @@ void luaD_call (lua_State *L, StkId func, int nresults) { | |||
| 466 | f = fvalue(s2v(func)); | 466 | f = fvalue(s2v(func)); |
| 467 | Cfunc: { | 467 | Cfunc: { |
| 468 | int n; /* number of returns */ | 468 | int n; /* number of returns */ |
| 469 | CallInfo *ci; | 469 | CallInfo *ci = next_ci(L); |
| 470 | checkstackp(L, LUA_MINSTACK, func); /* ensure minimum stack size */ | 470 | checkstackp(L, LUA_MINSTACK, func); /* ensure minimum stack size */ |
| 471 | ci = next_ci(L); | ||
| 472 | ci->nresults = nresults; | 471 | ci->nresults = nresults; |
| 473 | ci->callstatus = CIST_C; | 472 | ci->callstatus = CIST_C; |
| 474 | ci->top = L->top + LUA_MINSTACK; | 473 | ci->top = L->top + LUA_MINSTACK; |
| 475 | ci->func = func; | 474 | ci->func = func; |
| 475 | L->ci = ci; | ||
| 476 | lua_assert(ci->top <= L->stack_last); | 476 | lua_assert(ci->top <= L->stack_last); |
| 477 | if (L->hookmask & LUA_MASKCALL) { | 477 | if (L->hookmask & LUA_MASKCALL) { |
| 478 | int narg = cast_int(L->top - func) - 1; | 478 | int narg = cast_int(L->top - func) - 1; |
| @@ -486,18 +486,18 @@ void luaD_call (lua_State *L, StkId func, int nresults) { | |||
| 486 | break; | 486 | break; |
| 487 | } | 487 | } |
| 488 | case LUA_VLCL: { /* Lua function */ | 488 | case LUA_VLCL: { /* Lua function */ |
| 489 | CallInfo *ci; | 489 | CallInfo *ci = next_ci(L); |
| 490 | Proto *p = clLvalue(s2v(func))->p; | 490 | Proto *p = clLvalue(s2v(func))->p; |
| 491 | int narg = cast_int(L->top - func) - 1; /* number of real arguments */ | 491 | int narg = cast_int(L->top - func) - 1; /* number of real arguments */ |
| 492 | int nfixparams = p->numparams; | 492 | int nfixparams = p->numparams; |
| 493 | int fsize = p->maxstacksize; /* frame size */ | 493 | int fsize = p->maxstacksize; /* frame size */ |
| 494 | checkstackp(L, fsize, func); | 494 | checkstackp(L, fsize, func); |
| 495 | ci = next_ci(L); | ||
| 496 | ci->nresults = nresults; | 495 | ci->nresults = nresults; |
| 497 | ci->u.l.savedpc = p->code; /* starting point */ | 496 | ci->u.l.savedpc = p->code; /* starting point */ |
| 498 | ci->callstatus = 0; | 497 | ci->callstatus = 0; |
| 499 | ci->top = func + 1 + fsize; | 498 | ci->top = func + 1 + fsize; |
| 500 | ci->func = func; | 499 | ci->func = func; |
| 500 | L->ci = ci; | ||
| 501 | for (; narg < nfixparams; narg++) | 501 | for (; narg < nfixparams; narg++) |
| 502 | setnilvalue(s2v(L->top++)); /* complete missing arguments */ | 502 | setnilvalue(s2v(L->top++)); /* complete missing arguments */ |
| 503 | lua_assert(ci->top <= L->stack_last); | 503 | lua_assert(ci->top <= L->stack_last); |
| @@ -190,14 +190,15 @@ void luaE_freeCI (lua_State *L) { | |||
| 190 | */ | 190 | */ |
| 191 | void luaE_shrinkCI (lua_State *L) { | 191 | void luaE_shrinkCI (lua_State *L) { |
| 192 | CallInfo *ci = L->ci; | 192 | CallInfo *ci = L->ci; |
| 193 | CallInfo *next; | ||
| 193 | CallInfo *next2; /* next's next */ | 194 | CallInfo *next2; /* next's next */ |
| 194 | L->nCcalls += L->nci; /* add removed elements back to 'nCcalls' */ | 195 | L->nCcalls += L->nci; /* add removed elements back to 'nCcalls' */ |
| 195 | /* while there are two nexts */ | 196 | /* while there are two nexts */ |
| 196 | while (ci->next != NULL && (next2 = ci->next->next) != NULL) { | 197 | while ((next = ci->next) != NULL && (next2 = next->next) != NULL) { |
| 197 | luaM_free(L, ci->next); /* free next */ | 198 | ci->next = next2; /* remove next from the list */ |
| 198 | L->nci--; | ||
| 199 | ci->next = next2; /* remove 'next' from the list */ | ||
| 200 | next2->previous = ci; | 199 | next2->previous = ci; |
| 200 | luaM_free(L, next); /* free next */ | ||
| 201 | L->nci--; | ||
| 201 | ci = next2; /* keep next's next */ | 202 | ci = next2; /* keep next's next */ |
| 202 | } | 203 | } |
| 203 | L->nCcalls -= L->nci; /* adjust result */ | 204 | L->nCcalls -= L->nci; /* adjust result */ |
| @@ -173,7 +173,7 @@ typedef struct CallInfo { | |||
| 173 | union { | 173 | union { |
| 174 | struct { /* only for Lua functions */ | 174 | struct { /* only for Lua functions */ |
| 175 | const Instruction *savedpc; | 175 | const Instruction *savedpc; |
| 176 | l_signalT trap; | 176 | volatile l_signalT trap; |
| 177 | int nextraargs; /* # of extra arguments in vararg functions */ | 177 | int nextraargs; /* # of extra arguments in vararg functions */ |
| 178 | } l; | 178 | } l; |
| 179 | struct { /* only for C functions */ | 179 | struct { /* only for C functions */ |
| @@ -300,7 +300,7 @@ struct lua_State { | |||
| 300 | int stacksize; | 300 | int stacksize; |
| 301 | int basehookcount; | 301 | int basehookcount; |
| 302 | int hookcount; | 302 | int hookcount; |
| 303 | l_signalT hookmask; | 303 | volatile l_signalT hookmask; |
| 304 | }; | 304 | }; |
| 305 | 305 | ||
| 306 | 306 | ||
| @@ -54,8 +54,9 @@ static void lstop (lua_State *L, lua_Debug *ar) { | |||
| 54 | ** interpreter. | 54 | ** interpreter. |
| 55 | */ | 55 | */ |
| 56 | static void laction (int i) { | 56 | static void laction (int i) { |
| 57 | int flag = LUA_MASKCALL | LUA_MASKRET | LUA_MASKLINE | LUA_MASKCOUNT; | ||
| 57 | signal(i, SIG_DFL); /* if another SIGINT happens, terminate process */ | 58 | signal(i, SIG_DFL); /* if another SIGINT happens, terminate process */ |
| 58 | lua_sethook(globalL, lstop, LUA_MASKCALL | LUA_MASKRET | LUA_MASKCOUNT, 1); | 59 | lua_sethook(globalL, lstop, flag, 1); |
| 59 | } | 60 | } |
| 60 | 61 | ||
| 61 | 62 | ||
