aboutsummaryrefslogtreecommitdiff
path: root/testes
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2019-07-16 15:17:47 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2019-07-16 15:17:47 -0300
commitc220b0a5d099372e58e517b9f13eaa7bb0bec45c (patch)
tree5d5a083a4a7e924f5af052295cef49792305a989 /testes
parent298f383ffcc30d0799fbca0293175f647fe6bccf (diff)
downloadlua-c220b0a5d099372e58e517b9f13eaa7bb0bec45c.tar.gz
lua-c220b0a5d099372e58e517b9f13eaa7bb0bec45c.tar.bz2
lua-c220b0a5d099372e58e517b9f13eaa7bb0bec45c.zip
'__close' method may be called again in case of error
An error in a closing method may be caused by a lack of resources, such as memory or stack space, and the error may free enough resources (by unwinding the stack) to allow the method to work if called again. If the closing method is already running after some error (including its own), it is not called again.
Diffstat (limited to 'testes')
-rw-r--r--testes/locals.lua21
1 files changed, 14 insertions, 7 deletions
diff --git a/testes/locals.lua b/testes/locals.lua
index 1b82dd7f..73267d02 100644
--- a/testes/locals.lua
+++ b/testes/locals.lua
@@ -295,18 +295,23 @@ do -- errors in __close
295 local <toclose> y = 295 local <toclose> y =
296 func2close(function (self, msg) log[#log + 1] = msg; error(2) end) 296 func2close(function (self, msg) log[#log + 1] = msg; error(2) end)
297 local <toclose> z = 297 local <toclose> z =
298 func2close(function (self, msg) log[#log + 1] = msg or 10; error(3) end) 298 func2close(function (self, msg)
299 log[#log + 1] = (msg or 10) + 1;
300 error(3)
301 end)
299 if err then error(4) end 302 if err then error(4) end
300 end 303 end
301 local stat, msg = pcall(foo, false) 304 local stat, msg = pcall(foo, false)
302 assert(msg == 3) 305 assert(msg == 3)
303 assert(log[1] == 10 and log[2] == 3 and log[3] == 3 and log[4] == 3 306 -- 'z' close is called twice
304 and #log == 4) 307 assert(log[1] == 11 and log[2] == 4 and log[3] == 3 and log[4] == 3
308 and log[5] == 3 and #log == 5)
305 309
306 log = {} 310 log = {}
307 local stat, msg = pcall(foo, true) 311 local stat, msg = pcall(foo, true)
308 assert(msg == 4) 312 assert(msg == 4)
309 assert(log[1] == 4 and log[2] == 4 and log[3] == 4 and log[4] == 4 313 -- 'z' close is called once
314 assert(log[1] == 5 and log[2] == 4 and log[3] == 4 and log[4] == 4
310 and #log == 4) 315 and #log == 4)
311 316
312 -- error in toclose in vararg function 317 -- error in toclose in vararg function
@@ -495,15 +500,17 @@ do
495 local st, msg = pcall(co); assert(x == 2) 500 local st, msg = pcall(co); assert(x == 2)
496 assert(not st and msg == 200) -- should get first error raised 501 assert(not st and msg == 200) -- should get first error raised
497 502
498 x = 0 503 local x = 0
504 local y = 0
499 co = coroutine.wrap(function () 505 co = coroutine.wrap(function ()
500 local <toclose> xx = func2close(function () x = x + 1; error("YYY") end) 506 local <toclose> xx = func2close(function () y = y + 1; error("YYY") end)
501 local <toclose> xv = func2close(function () x = x + 1; error("XXX") end) 507 local <toclose> xv = func2close(function () x = x + 1; error("XXX") end)
502 coroutine.yield(100) 508 coroutine.yield(100)
503 return 200 509 return 200
504 end) 510 end)
505 assert(co() == 100); assert(x == 0) 511 assert(co() == 100); assert(x == 0)
506 local st, msg = pcall(co); assert(x == 2) 512 local st, msg = pcall(co)
513 assert(x == 2 and y == 1) -- first close is called twice
507 -- should get first error raised 514 -- should get first error raised
508 assert(not st and string.find(msg, "%w+%.%w+:%d+: XXX")) 515 assert(not st and string.find(msg, "%w+%.%w+:%d+: XXX"))
509end 516end