Bug: Wrong status in coroutine during reset
When closing variables during 'coroutine.close' or 'lua_resetthread', the status of a coroutine must be set to LUA_OK; a coroutine should not run with any other status. (See assertion in 'lua_callk'.) After the reset, the status should be kept as normal, as any error was already reported.
This commit is contained in:
@@ -136,6 +136,10 @@ do
|
||||
assert(coroutine.status(co) == "dead")
|
||||
local st, msg = coroutine.close(co)
|
||||
assert(st and msg == nil)
|
||||
-- also ok to close it again
|
||||
st, msg = coroutine.close(co)
|
||||
assert(st and msg == nil)
|
||||
|
||||
|
||||
-- cannot close the running coroutine
|
||||
local st, msg = pcall(coroutine.close, coroutine.running())
|
||||
@@ -149,6 +153,22 @@ do
|
||||
assert(not st and string.find(msg, "normal"))
|
||||
end))()
|
||||
|
||||
-- cannot close a coroutine while closing it
|
||||
do
|
||||
local co
|
||||
co = coroutine.create(
|
||||
function()
|
||||
local x <close> = func2close(function()
|
||||
coroutine.close(co) -- try to close it again
|
||||
end)
|
||||
coroutine.yield(20)
|
||||
end)
|
||||
local st, msg = coroutine.resume(co)
|
||||
assert(st and msg == 20)
|
||||
st, msg = coroutine.close(co)
|
||||
assert(not st and string.find(msg, "running coroutine"))
|
||||
end
|
||||
|
||||
-- to-be-closed variables in coroutines
|
||||
local X
|
||||
|
||||
@@ -158,6 +178,9 @@ do
|
||||
assert(not st and msg == 100)
|
||||
st, msg = coroutine.close(co)
|
||||
assert(not st and msg == 100)
|
||||
-- after closing, no more errors
|
||||
st, msg = coroutine.close(co)
|
||||
assert(st and msg == nil)
|
||||
|
||||
co = coroutine.create(function ()
|
||||
local x <close> = func2close(function (self, err)
|
||||
@@ -189,6 +212,9 @@ do
|
||||
local st, msg = coroutine.close(co)
|
||||
assert(st == false and coroutine.status(co) == "dead" and msg == 200)
|
||||
assert(x == 200)
|
||||
-- after closing, no more errors
|
||||
st, msg = coroutine.close(co)
|
||||
assert(st and msg == nil)
|
||||
end
|
||||
|
||||
do
|
||||
@@ -419,7 +445,7 @@ do
|
||||
|
||||
local X = false
|
||||
A = coroutine.wrap(function()
|
||||
local _ <close> = setmetatable({}, {__close = function () X = true end})
|
||||
local _ <close> = func2close(function () X = true end)
|
||||
return pcall(A, 1)
|
||||
end)
|
||||
st, res = A()
|
||||
@@ -427,6 +453,22 @@ do
|
||||
end
|
||||
|
||||
|
||||
-- bug in 5.4.1
|
||||
do
|
||||
-- coroutine ran close metamethods with invalid status during a
|
||||
-- reset.
|
||||
local co
|
||||
co = coroutine.wrap(function()
|
||||
local x <close> = func2close(function() return pcall(co) end)
|
||||
error(111)
|
||||
end)
|
||||
local st, errobj = pcall(co)
|
||||
assert(not st and errobj == 111)
|
||||
st, errobj = pcall(co)
|
||||
assert(not st and string.find(errobj, "dead coroutine"))
|
||||
end
|
||||
|
||||
|
||||
-- attempt to resume 'normal' coroutine
|
||||
local co1, co2
|
||||
co1 = coroutine.create(function () return co2() end)
|
||||
|
||||
Reference in New Issue
Block a user