فهرست منبع

The main thread cannot be closed

No thread started with pcall (instead of resume) can be closed,
because coroutine.close would not respect the expected number of
results from the protected call.
Roberto Ierusalimschy 1 ماه پیش
والد
کامیت
e657a48ea5
3فایلهای تغییر یافته به همراه10 افزوده شده و 2 حذف شده
  1. 3 0
      lcorolib.c
  2. 2 2
      manual/manual.of
  3. 5 0
      testes/coroutine.lua

+ 3 - 0
lcorolib.c

@@ -190,6 +190,9 @@ static int luaB_close (lua_State *L) {
       }
     }
     case COS_RUN:  /* running coroutine? */
+      lua_geti(L, LUA_REGISTRYINDEX, LUA_RIDX_MAINTHREAD);  /* get main */
+      if (lua_tothread(L, -1) == co)
+        return luaL_error(L, "cannot close main thread");
       lua_closethread(co, L);  /* close itself */
       lua_assert(0);  /* previous call does not return */
       return 0;

+ 2 - 2
manual/manual.of

@@ -3284,8 +3284,8 @@ If @id{L} is equal to @id{from},
 it corresponds to a thread closing itself.
 In that case,
 the call does not return;
-instead, the resume or the protected call
-that (re)started the thread returns.
+instead, the resume that (re)started the thread returns.
+The thread must be running inside a resume.
 
 }
 

+ 5 - 0
testes/coroutine.lua

@@ -158,6 +158,11 @@ do
 
   local main = coroutine.running()
 
+  -- cannot close 'main'
+  local st, msg = pcall(coroutine.close, main);
+  assert(not st and string.find(msg, "main"))
+
+
   -- cannot close a "normal" coroutine
   ;(coroutine.wrap(function ()
     local st, msg = pcall(coroutine.close, main)