commit d39ea8b3ce684728c1ad5005192766d39d2e8baa
parent 6298903e35217ab69c279056f925fb72900ce0b7
Author: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
Date: Mon, 6 Jul 2020 13:53:34 -0300
Make sure that main thread is non yieldable
Main thread must be non yieldable even at "level 0" (bare API), outside
the 'pcall' from 'lua.c'.
Diffstat:
3 files changed, 18 insertions(+), 4 deletions(-)
diff --git a/lstate.c b/lstate.c
@@ -395,6 +395,7 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
g->allgc = obj2gco(L); /* by now, only object is the main thread */
L->next = NULL;
g->Cstacklimit = L->nCcalls = LUAI_MAXCSTACK + CSTACKERR;
+ incnny(L); /* main thread is always non yieldable */
g->frealloc = f;
g->ud = ud;
g->warnf = NULL;
diff --git a/ltests.c b/ltests.c
@@ -145,7 +145,6 @@ static void warnf (void *ud, const char *msg, int tocont) {
lua_pushstring(L, buff);
lua_setglobal(L, "_WARN"); /* assign message to global '_WARN' */
lua_lock(L);
- buff[0] = '\0'; /* prepare buffer for next warning */
break;
}
}
@@ -749,11 +748,12 @@ static int listlocals (lua_State *L) {
static void printstack (lua_State *L) {
int i;
int n = lua_gettop(L);
+ printf("stack: >>\n");
for (i = 1; i <= n; i++) {
printf("%3d: %s\n", i, luaL_tolstring(L, i, NULL));
lua_pop(L, 1);
}
- printf("\n");
+ printf("<<\n");
}
@@ -1678,6 +1678,9 @@ static struct X { int x; } x;
if (n == 0) n = lua_gettop(fs);
lua_xmove(fs, ts, n);
}
+ else if EQ("isyieldable") {
+ lua_pushboolean(L1, lua_isyieldable(lua_tothread(L1, getindex)));
+ }
else if EQ("yield") {
return lua_yield(L1, getnum);
}
diff --git a/testes/coroutine.lua b/testes/coroutine.lua
@@ -407,7 +407,8 @@ assert(_G.f() == 12)
if not T then
- (Message or print)('\n >>> testC not active: skipping yield/hook tests <<<\n')
+ (Message or print)
+ ('\n >>> testC not active: skipping coroutine API tests <<<\n')
else
print "testing yields inside hooks"
@@ -564,8 +565,17 @@ else
c == "ERRRUN" and d == 4)
- -- using a main thread as a coroutine
+ -- using a main thread as a coroutine (dubious use!)
local state = T.newstate()
+
+ -- check that yielddable is working correctly
+ assert(T.testC(state, "newthread; isyieldable -1; remove 1; return 1"))
+
+ -- main thread is not yieldable
+ assert(not T.testC(state, "rawgeti R 1; isyieldable -1; remove 1; return 1"))
+
+ T.testC(state, "settop 0")
+
T.loadlib(state)
assert(T.doremote(state, [[