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, [[ |
