diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2020-07-06 13:54:01 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2020-07-06 13:54:01 -0300 |
commit | d39ea8b3ce684728c1ad5005192766d39d2e8baa (patch) | |
tree | a6366af9c0fb14af5b244b609cbc3da2b652b798 | |
parent | 6298903e35217ab69c279056f925fb72900ce0b7 (diff) | |
download | lua-d39ea8b3ce684728c1ad5005192766d39d2e8baa.tar.gz lua-d39ea8b3ce684728c1ad5005192766d39d2e8baa.tar.bz2 lua-d39ea8b3ce684728c1ad5005192766d39d2e8baa.zip |
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'.
-rw-r--r-- | lstate.c | 1 | ||||
-rw-r--r-- | ltests.c | 7 | ||||
-rw-r--r-- | testes/coroutine.lua | 14 |
3 files changed, 18 insertions, 4 deletions
@@ -395,6 +395,7 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { | |||
395 | g->allgc = obj2gco(L); /* by now, only object is the main thread */ | 395 | g->allgc = obj2gco(L); /* by now, only object is the main thread */ |
396 | L->next = NULL; | 396 | L->next = NULL; |
397 | g->Cstacklimit = L->nCcalls = LUAI_MAXCSTACK + CSTACKERR; | 397 | g->Cstacklimit = L->nCcalls = LUAI_MAXCSTACK + CSTACKERR; |
398 | incnny(L); /* main thread is always non yieldable */ | ||
398 | g->frealloc = f; | 399 | g->frealloc = f; |
399 | g->ud = ud; | 400 | g->ud = ud; |
400 | g->warnf = NULL; | 401 | g->warnf = NULL; |
@@ -145,7 +145,6 @@ static void warnf (void *ud, const char *msg, int tocont) { | |||
145 | lua_pushstring(L, buff); | 145 | lua_pushstring(L, buff); |
146 | lua_setglobal(L, "_WARN"); /* assign message to global '_WARN' */ | 146 | lua_setglobal(L, "_WARN"); /* assign message to global '_WARN' */ |
147 | lua_lock(L); | 147 | lua_lock(L); |
148 | buff[0] = '\0'; /* prepare buffer for next warning */ | ||
149 | break; | 148 | break; |
150 | } | 149 | } |
151 | } | 150 | } |
@@ -749,11 +748,12 @@ static int listlocals (lua_State *L) { | |||
749 | static void printstack (lua_State *L) { | 748 | static void printstack (lua_State *L) { |
750 | int i; | 749 | int i; |
751 | int n = lua_gettop(L); | 750 | int n = lua_gettop(L); |
751 | printf("stack: >>\n"); | ||
752 | for (i = 1; i <= n; i++) { | 752 | for (i = 1; i <= n; i++) { |
753 | printf("%3d: %s\n", i, luaL_tolstring(L, i, NULL)); | 753 | printf("%3d: %s\n", i, luaL_tolstring(L, i, NULL)); |
754 | lua_pop(L, 1); | 754 | lua_pop(L, 1); |
755 | } | 755 | } |
756 | printf("\n"); | 756 | printf("<<\n"); |
757 | } | 757 | } |
758 | 758 | ||
759 | 759 | ||
@@ -1678,6 +1678,9 @@ static struct X { int x; } x; | |||
1678 | if (n == 0) n = lua_gettop(fs); | 1678 | if (n == 0) n = lua_gettop(fs); |
1679 | lua_xmove(fs, ts, n); | 1679 | lua_xmove(fs, ts, n); |
1680 | } | 1680 | } |
1681 | else if EQ("isyieldable") { | ||
1682 | lua_pushboolean(L1, lua_isyieldable(lua_tothread(L1, getindex))); | ||
1683 | } | ||
1681 | else if EQ("yield") { | 1684 | else if EQ("yield") { |
1682 | return lua_yield(L1, getnum); | 1685 | return lua_yield(L1, getnum); |
1683 | } | 1686 | } |
diff --git a/testes/coroutine.lua b/testes/coroutine.lua index 0a4c2ef3..955f6776 100644 --- a/testes/coroutine.lua +++ b/testes/coroutine.lua | |||
@@ -407,7 +407,8 @@ assert(_G.f() == 12) | |||
407 | 407 | ||
408 | 408 | ||
409 | if not T then | 409 | if not T then |
410 | (Message or print)('\n >>> testC not active: skipping yield/hook tests <<<\n') | 410 | (Message or print) |
411 | ('\n >>> testC not active: skipping coroutine API tests <<<\n') | ||
411 | else | 412 | else |
412 | print "testing yields inside hooks" | 413 | print "testing yields inside hooks" |
413 | 414 | ||
@@ -564,8 +565,17 @@ else | |||
564 | c == "ERRRUN" and d == 4) | 565 | c == "ERRRUN" and d == 4) |
565 | 566 | ||
566 | 567 | ||
567 | -- using a main thread as a coroutine | 568 | -- using a main thread as a coroutine (dubious use!) |
568 | local state = T.newstate() | 569 | local state = T.newstate() |
570 | |||
571 | -- check that yielddable is working correctly | ||
572 | assert(T.testC(state, "newthread; isyieldable -1; remove 1; return 1")) | ||
573 | |||
574 | -- main thread is not yieldable | ||
575 | assert(not T.testC(state, "rawgeti R 1; isyieldable -1; remove 1; return 1")) | ||
576 | |||
577 | T.testC(state, "settop 0") | ||
578 | |||
569 | T.loadlib(state) | 579 | T.loadlib(state) |
570 | 580 | ||
571 | assert(T.doremote(state, [[ | 581 | assert(T.doremote(state, [[ |