summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2020-05-22 11:40:34 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2020-05-22 11:40:34 -0300
commit17dbaa8639505c9ad1a9946591f5960123fbd741 (patch)
treec078795bfb4a748ca05faabefafab4e35493714a
parent9514abc2da3525ef4314a8fcf70982ad07319e51 (diff)
downloadlua-github-17dbaa8639505c9ad1a9946591f5960123fbd741.tar.gz
Improvements in the handling of signals
Added 'volatile' to 'l_signalT' variables plus some minor changes.
-rw-r--r--ldebug.c20
-rw-r--r--ldo.c10
-rw-r--r--lstate.c9
-rw-r--r--lstate.h4
-rw-r--r--lua.c3
5 files changed, 25 insertions, 21 deletions
diff --git a/ldebug.c b/ldebug.c
index eaac16f7..afdc2b74 100644
--- a/ldebug.c
+++ b/ldebug.c
@@ -107,13 +107,15 @@ static int getcurrentline (CallInfo *ci) {
/*
-** This function can be called asynchronously (e.g. during a signal),
-** under "reasonable" assumptions. A new 'ci' is completely linked
-** in the list before it becomes part of the "active" list, and
-** we assume that pointers are atomic (see comment in next function).
-** (If we traverse one more item, there is no problem. If we traverse
-** one less item, the worst that can happen is that the signal will
-** not interrupt the script.)
+** Set 'trap' for all active Lua frames.
+** This function can be called during a signal, under "reasonable"
+** assumptions. A new 'ci' is completely linked in the list before it
+** becomes part of the "active" list, and we assume that pointers are
+** atomic; see comment in next function.
+** (A compiler doing interprocedural optimizations could, theoretically,
+** reorder memory writes in such a way that the list could be
+** temporarily broken while inserting a new element. We simply assume it
+** has no good reasons to do that.)
*/
static void settraps (CallInfo *ci) {
for (; ci != NULL; ci = ci->previous)
@@ -123,8 +125,8 @@ static void settraps (CallInfo *ci) {
/*
-** This function can be called asynchronously (e.g. during a signal),
-** under "reasonable" assumptions.
+** This function can be called during a signal, under "reasonable"
+** assumptions.
** Fields 'oldpc', 'basehookcount', and 'hookcount' (set by
** 'resethookcount') are for debug only, and it is no problem if they
** get arbitrary values (causes at most one wrong hook call). 'hookmask'
diff --git a/ldo.c b/ldo.c
index 64fe2915..c563b1d9 100644
--- a/ldo.c
+++ b/ldo.c
@@ -422,7 +422,7 @@ void luaD_poscall (lua_State *L, CallInfo *ci, int nres) {
-#define next_ci(L) (L->ci = (L->ci->next ? L->ci->next : luaE_extendCI(L)))
+#define next_ci(L) (L->ci->next ? L->ci->next : luaE_extendCI(L))
/*
@@ -466,13 +466,13 @@ void luaD_call (lua_State *L, StkId func, int nresults) {
f = fvalue(s2v(func));
Cfunc: {
int n; /* number of returns */
- CallInfo *ci;
+ CallInfo *ci = next_ci(L);
checkstackp(L, LUA_MINSTACK, func); /* ensure minimum stack size */
- ci = next_ci(L);
ci->nresults = nresults;
ci->callstatus = CIST_C;
ci->top = L->top + LUA_MINSTACK;
ci->func = func;
+ L->ci = ci;
lua_assert(ci->top <= L->stack_last);
if (L->hookmask & LUA_MASKCALL) {
int narg = cast_int(L->top - func) - 1;
@@ -486,18 +486,18 @@ void luaD_call (lua_State *L, StkId func, int nresults) {
break;
}
case LUA_VLCL: { /* Lua function */
- CallInfo *ci;
+ CallInfo *ci = next_ci(L);
Proto *p = clLvalue(s2v(func))->p;
int narg = cast_int(L->top - func) - 1; /* number of real arguments */
int nfixparams = p->numparams;
int fsize = p->maxstacksize; /* frame size */
checkstackp(L, fsize, func);
- ci = next_ci(L);
ci->nresults = nresults;
ci->u.l.savedpc = p->code; /* starting point */
ci->callstatus = 0;
ci->top = func + 1 + fsize;
ci->func = func;
+ L->ci = ci;
for (; narg < nfixparams; narg++)
setnilvalue(s2v(L->top++)); /* complete missing arguments */
lua_assert(ci->top <= L->stack_last);
diff --git a/lstate.c b/lstate.c
index 8fba70d7..42a48436 100644
--- a/lstate.c
+++ b/lstate.c
@@ -190,14 +190,15 @@ void luaE_freeCI (lua_State *L) {
*/
void luaE_shrinkCI (lua_State *L) {
CallInfo *ci = L->ci;
+ CallInfo *next;
CallInfo *next2; /* next's next */
L->nCcalls += L->nci; /* add removed elements back to 'nCcalls' */
/* while there are two nexts */
- while (ci->next != NULL && (next2 = ci->next->next) != NULL) {
- luaM_free(L, ci->next); /* free next */
- L->nci--;
- ci->next = next2; /* remove 'next' from the list */
+ while ((next = ci->next) != NULL && (next2 = next->next) != NULL) {
+ ci->next = next2; /* remove next from the list */
next2->previous = ci;
+ luaM_free(L, next); /* free next */
+ L->nci--;
ci = next2; /* keep next's next */
}
L->nCcalls -= L->nci; /* adjust result */
diff --git a/lstate.h b/lstate.h
index df9148eb..2e8bd6c4 100644
--- a/lstate.h
+++ b/lstate.h
@@ -173,7 +173,7 @@ typedef struct CallInfo {
union {
struct { /* only for Lua functions */
const Instruction *savedpc;
- l_signalT trap;
+ volatile l_signalT trap;
int nextraargs; /* # of extra arguments in vararg functions */
} l;
struct { /* only for C functions */
@@ -300,7 +300,7 @@ struct lua_State {
int stacksize;
int basehookcount;
int hookcount;
- l_signalT hookmask;
+ volatile l_signalT hookmask;
};
diff --git a/lua.c b/lua.c
index 18f53c30..454ce12f 100644
--- a/lua.c
+++ b/lua.c
@@ -54,8 +54,9 @@ static void lstop (lua_State *L, lua_Debug *ar) {
** interpreter.
*/
static void laction (int i) {
+ int flag = LUA_MASKCALL | LUA_MASKRET | LUA_MASKLINE | LUA_MASKCOUNT;
signal(i, SIG_DFL); /* if another SIGINT happens, terminate process */
- lua_sethook(globalL, lstop, LUA_MASKCALL | LUA_MASKRET | LUA_MASKCOUNT, 1);
+ lua_sethook(globalL, lstop, flag, 1);
}