lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


I'm curious about these to be closed variables.

When closing a thread with lua_resetthread, can you manually specify the error object which is used when calling the __close metamethods?
For example:

local t<close> = setmetatable({},{__close=function(_,err)print(err)end})
error"a"

Will print out the error object
But

local thread = coroutine.create(function()
    local t<close> = setmetatable({},{__close=function(_,err)print(err)end})
    error"a"
end)
coroutine.resume(thread)
coroutine.close(thread)

Will print out nil
What i'm looking for:

local thread = coroutine.create(function()
    local t<close> = setmetatable({},{__close=function(_,err)print(err)end})
    error"a"
end)
local success,err = coroutine.resume(thread)
if not success then
    coroutine.close(thread,err-- use second argument as error object
end

If this isn't possible currently, could it be added?

I would do this from the C api so, perhaps use the top value from the stack of the thread that is being closed (or nil), when closing the thread?

Also, why can only one to be closed variable be declared in a multi assignment?

local x<close>,y

Is valid
but not

local x<close>,y<close>

Using to-be-closed variable for recursion seems to allow __close to be called an unlimited amount of times. This only appears to happen when closing a variable for the second time.

local function closeF(self)
    local traceback = debug.traceback()
    local skip = tonumber(string.match(traceback,"%(skipping (%d+) levels%)") or "0")
    local count = 0
    local init = 0
    while init do
        init = init + 1
        init = string.find(traceback,"\n",init,true)
        count = count + 1
    end
    print(count-1+skip)
    local t<close> = self
end
local t<close> = setmetatable({},{__close=closeF})

The stack level goes up then starts over again

Another example with coroutines

local first = true
local thread = coroutine.create(function()
    local function closeF(self)
        if first then
            print"first to-be-closed"
            first = false
        end
        local t<close> = self
    end
    local t2<close> = setmetatable({},{__close=function()print"second to-be-closed"end})
    local t<close> = setmetatable({},{__close=closeF})
end)
print"step 1"
print("resume:",coroutine.resume(thread))
print"step 2"
first = true
print("close:",coroutine.close(thread))
print"step 3"

step 3 is never printed, and the first time that __close is called on t it stops and errors with C stack overflow which is caught, but the second time it keeps going on, and on, and on. If on the second time it is stopped after when it should have errored with C stack overflow, it errors with C stack overflow which is caught by coroutine.close

I assume this is a bug?