Просмотр исходного кода

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'.
Roberto Ierusalimschy 5 лет назад
Родитель
Сommit
d39ea8b3ce
3 измененных файлов с 18 добавлено и 4 удалено
  1. 1 0
      lstate.c
  2. 5 2
      ltests.c
  3. 12 2
      testes/coroutine.lua

+ 1 - 0
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;

+ 5 - 2
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);
     }

+ 12 - 2
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, [[