From ce101dcaf73ff6d610593230d41b63c163a91519 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Wed, 30 Dec 2020 11:20:22 -0300 Subject: 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'. --- testes/coroutine.lua | 41 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) (limited to 'testes') 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 = o + return 1 + end + + local function foo () + local x = func2close(function(_,msg) + track[#track + 1] = msg or false + error(20) + end) + local y = func2close(function(_,msg) + track[#track + 1] = msg or false + return 1000 + end) + local z = 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 -- cgit v1.2.3-55-g6feb