mirror of https://github.com/rusefi/lua.git
'coroutine.close'/'lua_resetthread' report original errors
Besides errors in closing methods, 'coroutine.close' and 'lua_resetthread' also consider the original error that stopped the thread, if any.
This commit is contained in:
parent
b17178b27a
commit
409256b784
8
lstate.c
8
lstate.c
|
@ -323,14 +323,16 @@ void luaE_freethread (lua_State *L, lua_State *L1) {
|
|||
|
||||
int lua_resetthread (lua_State *L) {
|
||||
CallInfo *ci;
|
||||
int status;
|
||||
int status = L->status;
|
||||
lua_lock(L);
|
||||
L->ci = ci = &L->base_ci; /* unwind CallInfo list */
|
||||
setnilvalue(s2v(L->stack)); /* 'function' entry for basic 'ci' */
|
||||
ci->func = L->stack;
|
||||
ci->callstatus = CIST_C;
|
||||
status = luaF_close(L, L->stack, CLOSEPROTECT);
|
||||
if (status != CLOSEPROTECT) /* real errors? */
|
||||
if (status == LUA_OK || status == LUA_YIELD)
|
||||
status = CLOSEPROTECT; /* run closing methods in protected mode */
|
||||
status = luaF_close(L, L->stack, status);
|
||||
if (status != CLOSEPROTECT) /* errors? */
|
||||
luaD_seterrorobj(L, status, L->stack + 1);
|
||||
else {
|
||||
status = LUA_OK;
|
||||
|
|
|
@ -4098,10 +4098,12 @@ and then pops the top element.
|
|||
Resets a thread, cleaning its call stack and closing all pending
|
||||
to-be-closed variables.
|
||||
Returns a status code:
|
||||
@Lid{LUA_OK} for no errors in closing methods,
|
||||
@Lid{LUA_OK} for no errors in the thread
|
||||
(either the original error that stopped the thread or
|
||||
errors in closing methods),
|
||||
or an error status otherwise.
|
||||
In case of error,
|
||||
leaves the error object on the top of the stack,
|
||||
leaves the error object on the top of the stack.
|
||||
|
||||
}
|
||||
|
||||
|
@ -6577,7 +6579,9 @@ that is,
|
|||
closes all its pending to-be-closed variables
|
||||
and puts the coroutine in a dead state.
|
||||
The given coroutine must be dead or suspended.
|
||||
In case of error closing some variable,
|
||||
In case of error
|
||||
(either the original error that stopped the coroutine or
|
||||
errors in closing methods),
|
||||
returns @false plus the error object;
|
||||
otherwise returns @true.
|
||||
|
||||
|
|
|
@ -134,7 +134,8 @@ do
|
|||
local co = coroutine.create(print)
|
||||
assert(coroutine.resume(co, "testing 'coroutine.close'"))
|
||||
assert(coroutine.status(co) == "dead")
|
||||
assert(coroutine.close(co))
|
||||
local st, msg = coroutine.close(co)
|
||||
assert(st and msg == nil)
|
||||
|
||||
-- cannot close the running coroutine
|
||||
local st, msg = pcall(coroutine.close, coroutine.running())
|
||||
|
@ -151,6 +152,13 @@ do
|
|||
-- to-be-closed variables in coroutines
|
||||
local X
|
||||
|
||||
-- closing a coroutine after an error
|
||||
local co = coroutine.create(error)
|
||||
local st, msg = coroutine.resume(co, 100)
|
||||
assert(not st and msg == 100)
|
||||
st, msg = coroutine.close(co)
|
||||
assert(not st and msg == 100)
|
||||
|
||||
co = coroutine.create(function ()
|
||||
local x <close> = func2close(function (self, err)
|
||||
assert(err == nil); X = false
|
||||
|
|
|
@ -135,14 +135,18 @@ if T then
|
|||
local topB, sizeB -- top and size Before overflow
|
||||
local topA, sizeA -- top and size After overflow
|
||||
topB, sizeB = T.stacklevel()
|
||||
collectgarbage("stop") -- __gc should not be called with a full stack
|
||||
xpcall(f, err)
|
||||
collectgarbage("restart")
|
||||
topA, sizeA = T.stacklevel()
|
||||
-- sizes should be comparable
|
||||
assert(topA == topB and sizeA < sizeB * 2)
|
||||
print(string.format("maximum stack size: %d", stack1))
|
||||
LIM = N -- will stop recursion at maximum level
|
||||
N = 0 -- to count again
|
||||
collectgarbage("stop") -- __gc should not be called with a full stack
|
||||
f()
|
||||
collectgarbage("restart")
|
||||
print"+"
|
||||
end
|
||||
|
||||
|
|
|
@ -362,7 +362,7 @@ end
|
|||
|
||||
local function checkwarn (msg)
|
||||
if T then
|
||||
assert(string.find(_WARN, msg))
|
||||
assert(_WARN and string.find(_WARN, msg))
|
||||
_WARN = false -- reset variable to check next warning
|
||||
end
|
||||
end
|
||||
|
@ -670,10 +670,13 @@ do
|
|||
-- error in a wrapped coroutine raising errors when closing a variable
|
||||
local x = 0
|
||||
local co = coroutine.wrap(function ()
|
||||
local xx <close> = func2close(function () x = x + 1; error("@YYY") end)
|
||||
local xx <close> = func2close(function ()
|
||||
x = x + 1;
|
||||
checkwarn("@XXX"); error("@YYY")
|
||||
end)
|
||||
local xv <close> = func2close(function () x = x + 1; error("@XXX") end)
|
||||
coroutine.yield(100)
|
||||
error(200)
|
||||
coroutine.yield(100)
|
||||
error(200)
|
||||
end)
|
||||
assert(co() == 100); assert(x == 0)
|
||||
local st, msg = pcall(co); assert(x == 2)
|
||||
|
@ -683,10 +686,14 @@ do
|
|||
local x = 0
|
||||
local y = 0
|
||||
co = coroutine.wrap(function ()
|
||||
local xx <close> = func2close(function () y = y + 1; error("YYY") end)
|
||||
local xv <close> = func2close(function () x = x + 1; error("XXX") end)
|
||||
coroutine.yield(100)
|
||||
return 200
|
||||
local xx <close> = func2close(function ()
|
||||
y = y + 1; checkwarn("XXX"); error("YYY")
|
||||
end)
|
||||
local xv <close> = func2close(function ()
|
||||
x = x + 1; error("XXX")
|
||||
end)
|
||||
coroutine.yield(100)
|
||||
return 200
|
||||
end)
|
||||
assert(co() == 100); assert(x == 0)
|
||||
local st, msg = pcall(co)
|
||||
|
|
Loading…
Reference in New Issue