summaryrefslogtreecommitdiff
path: root/testes/coroutine.lua
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2020-12-30 11:20:22 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2020-12-30 11:20:22 -0300
commitce101dcaf73ff6d610593230d41b63c163a91519 (patch)
tree6417f02cb96257a835fa908bfea15c2557a41413 /testes/coroutine.lua
parent553b37ce4ff758d8cf80d48a21287526c92221c6 (diff)
downloadlua-github-ce101dcaf73ff6d610593230d41b63c163a91519.tar.gz
Handles '__close' errors in coroutines in "coroutine style"
Errors in '__close' metamethods in coroutines are handled by the same logic that handles other errors, through 'recover'.
Diffstat (limited to 'testes/coroutine.lua')
-rw-r--r--testes/coroutine.lua41
1 files changed, 39 insertions, 2 deletions
diff --git a/testes/coroutine.lua b/testes/coroutine.lua
index 0a970e98..fbeabd07 100644
--- a/testes/coroutine.lua
+++ b/testes/coroutine.lua
@@ -123,7 +123,7 @@ assert(#a == 22 and a[#a] == 79)
x, a = nil
--- coroutine closing
+print("to-be-closed variables in coroutines")
local function func2close (f)
return setmetatable({}, {__close = f})
@@ -189,7 +189,6 @@ do
local st, msg = coroutine.close(co)
assert(st == false and coroutine.status(co) == "dead" and msg == 200)
assert(x == 200)
-
end
do
@@ -207,6 +206,44 @@ do
local st1, st2, err = coroutine.resume(co)
assert(st1 and not st2 and err == 43)
assert(X == 43 and Y.name == "pcall")
+
+ -- recovering from errors in __close metamethods
+ local track = {}
+
+ local function h (o)
+ local hv <close> = o
+ return 1
+ end
+
+ local function foo ()
+ local x <close> = func2close(function(_,msg)
+ track[#track + 1] = msg or false
+ error(20)
+ end)
+ local y <close> = func2close(function(_,msg)
+ track[#track + 1] = msg or false
+ return 1000
+ end)
+ local z <close> = func2close(function(_,msg)
+ track[#track + 1] = msg or false
+ error(10)
+ end)
+ coroutine.yield(1)
+ h(func2close(function(_,msg)
+ track[#track + 1] = msg or false
+ error(2)
+ end))
+ end
+
+ local co = coroutine.create(pcall)
+
+ local st, res = coroutine.resume(co, foo) -- call 'foo' protected
+ assert(st and res == 1) -- yield 1
+ local st, res1, res2 = coroutine.resume(co) -- continue
+ assert(coroutine.status(co) == "dead")
+ assert(st and not res1 and res2 == 20) -- last error (20)
+ assert(track[1] == false and track[2] == 2 and track[3] == 10 and
+ track[4] == 10)
end