[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: RE: dawn of the dead: dead coroutine as a key in a __mode="v" table
- From: "Jerome Vuarand" <jerome.vuarand@...>
- Date: Thu, 16 Nov 2006 17:31:08 -0500
I don't understand your problem there. When I run your test, the first
print displays nil, and coroutine.status throw an error because a is not
a coroutine. That's the expected behaviour of that code.
Is there a bug on your platform, or did you expect a different behaviour
?
Karel Tuma wrote:
> hello list,
>
> recently i've spent few hours finding out "mysterious memory leaks"
> in one erlang-like system written in lua.
>
> some of you have probably been bitten by what i call "lua's weak
> paradox", that is
>
> http://lua-users.org/wiki/GarbageCollectingWeakTable
>
> basically it means that weak element (either key or value) of
> a table wont
> get garbage collected if there exists _any_ reachable strong
> path to that
> value, including the strong part of the table row in question.
> somehow, it's so wicked it actually sounds right.
> naturally, from my experience i thought this applies only to
> tables with
> either cyclic weak key or value, but still i got bitten by
> this "feature"
> today:
>
> weak = {}
> setmetatable(weak, {__mode = "v"})
>
> a = {}
> b = coroutine.create(function(x) error() end)
>
> -- b still has "strong" reference to a
> weak[b] = a
>
> -- now there are no references to 'a' except the dead coroutine
> a = nil
> b = nil
>
> -- the table has value of 'a' although noone is referring to it
> collectgarbage("collect")
> print(next(weak))
>
> -- kill the value on dead's coroutine stack
> a = next(weak)
> print(coroutine.status(a))
> debug.setlocal(a, 1, 1, "die hard")
> collectgarbage("collect")
>
> -- now the table is empty
> print(next(weak))
>
> as you can see, there is something wrong with this. the "dead"
> coroutine makes "strong" reference to 'a' but there is no way
> to kill that reference in the first place. i'd understand this
> if it would be open upvalue, or the coroutine alive, but come on,
> what's purpose of completely dead coroutine's stack making strong
> references to my weak values?
>
> solution to this should be simple: ignore references from dead
> coroutine's stack, i'm now trying to figure out how to hack this
> into lua's gc (which is the most mysterious part of lua for me :)
> the question is: will this break something? i know that coroutine's
> upvalues should be left strong but i guess there will be also
> something else because otherwise i dont see any rationale behind
> this evil plot of coroutine walking zombies ;)
>
> //kt