lua-users home
lua-l archive

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




On Fri, Sep 16, 2011 at 3:18 PM, Gregory Bonik <gregory@bonik.org> wrote:
Gaspard Bucher wrote:
> I do not have any finalizers in the userdata.

I think it doesn't really matter. The fact is that garbage collector
sometimes doesn't collect all garbage in one cycle. One possible cause
are finalizers. In your case, it's probably a complicated dependency
graph with circular references. (For curiosity's sake, try to run
collectgarbage() multiple times instead of one and see if the program
still crashes)

Combined with weak tables, this can be dangerous. I believe that one
should not rely on GC to remove entries from weak tables (probably
except the case of "direct cache" when userdata are values in a weak
table), and remove these entries manually.

I think this shouldn't be considered a bug in Lua, but rather a feature
of its garbage collector and weak table semantics.

--Gregory

Effectively, running it twice avoids the crash.

I do not think this is just a feature of the garbage collector and weak table: it
would imply that we can never trust what is held through a weak table ! It can
break with one level deep, two, three, who knows ? And we have absolutely
no way to tell which part of what the weak table holds valid or invalid data.

The only solution would be to have the object cleanup after itself when it is
garbage collected, but this cannot be done for regular tables (and these are
holding the data: we cannot expect every userdata object (socket, timer, etc)
to know how to unregister themselves...

I think this is not as black and white: there must be some well defined "danger
zones" (like the env/thread stuff in https://gist.github.com/1221403) which
when properly avoided keep our code secure.

Roberto, can you confirm that there is a "safe" zone ? Or do we have to
use some special userdata which would run a finalizer to clear the weak
table ?

                                                               Gaspard