github.com/arnodel/golua@v0.0.0-20230215163904-e0b5347eaaa1/runtime/lua/thread.lua (about)

     1  do
     2      local f = coroutine.wrap(function()
     3          coroutine.yield(1)
     4          coroutine.yield(2)
     5          return 3
     6      end)
     7      print(f(), f(), f())
     8      --> =1	2	3
     9  
    10      print(pcall(f))
    11      --> ~^false\t.*dead thread
    12  end
    13  
    14  do
    15      local co = coroutine.create(function ()
    16          local t = coroutine.running()
    17          print(coroutine.resume(t))
    18          --> ~^false\t.*running thread
    19          print(coroutine.status(t))
    20          --> =running
    21      end)
    22      coroutine.resume(co)
    23      print(coroutine.status(co))
    24      --> =dead
    25  end
    26  
    27  do
    28      print(pcall(coroutine.yield, 1))
    29      --> ~cannot yield from main thread
    30  end
    31  
    32  -- Closing a coroutine
    33  do
    34      local co = coroutine.create(function() end)
    35  
    36      print(coroutine.close(co))
    37      --> =true
    38  
    39      -- A closed thread is dead
    40      print(coroutine.status(co))
    41      --> =dead
    42  
    43      -- It can be done again
    44      print(coroutine.close(co))
    45      --> =true
    46  
    47      -- Can't close the runnnig coroutine
    48      local main = coroutine.running()
    49      print(pcall(coroutine.close, main))
    50      --> ~false\t.*cannot close running thread
    51  
    52      local co = coroutine.create(function()
    53          print(pcall(coroutine.close, main))
    54          --> ~false\t.*cannot close normal thread
    55      end)
    56      coroutine.resume(co)
    57  
    58      -- Closing an errored thread returns the error
    59      local co = coroutine.create(error)
    60  
    61      print(coroutine.resume(co, 42))
    62      --> =false	42
    63  
    64      print(coroutine.close(co))
    65      --> =false	42
    66  end
    67  
    68  --
    69  -- Coroutines and to-be-closed variables
    70  --
    71  
    72  function make(msg, err)
    73      t = {}
    74      setmetatable(t, {__close = function (x, e) 
    75          if e ~= nil then
    76              print(msg, e)
    77          else
    78              print(msg)
    79          end
    80          if err ~= nil then 
    81              error(err)
    82          end
    83      end})
    84      return t
    85  end
    86  
    87  do
    88      local co = coroutine.create(function ()
    89          local foo <close> = make("foo")
    90          coroutine.yield()
    91      end)
    92      coroutine.resume(co)
    93      print(coroutine.status(co))
    94      --> =suspended
    95      print(coroutine.close(co))
    96      -- Output from closing the "foo" var
    97      --> =foo
    98      -- Outcome of coroutine.close(co)
    99      --> =true
   100      print(coroutine.status(co))
   101      --> =dead
   102  end
   103  
   104  do
   105      local function f(n)
   106          local x <close> = make("x"..n)
   107          if n > 1 then
   108              f(n - 1)
   109          else
   110              coroutine.yield()
   111          end
   112      end
   113      local co = coroutine.create(f)
   114      coroutine.resume(co, 3)
   115      print(coroutine.status(co))
   116      --> =suspended
   117      print(coroutine.close(co))
   118      -- Output from closing the "x" vars
   119      --> =x1
   120      --> =x2
   121      --> =x3
   122      -- Outcome of coroutine.close(co)
   123      --> =true
   124      print(coroutine.status(co))
   125      --> =dead
   126  end
   127  
   128  -- Wrapping this in pcall to suppress the default message handler which is
   129  -- adding traceback to error messages...
   130  pcall(function()
   131      local function f(n)
   132          local x <close> = make("x"..n, "ERR"..n)
   133          if n > 1 then
   134              f(n - 1)
   135          else
   136              coroutine.yield()
   137          end
   138      end
   139      local co = coroutine.create(f)
   140      coroutine.resume(co, 3)
   141      print(coroutine.status(co))
   142      --> =suspended
   143      print(coroutine.close(co))
   144      -- Output from closing the "x" vars
   145      --> =x1
   146      --> ~x2\t.*ERR1
   147      --> ~x3\t.*ERR2
   148      -- Outcome of coroutine.close(co)
   149      --> ~false\t.*ERR3
   150      print(coroutine.status(co))
   151      --> =dead
   152  end)