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)