lua-users home
lua-l archive

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

> >First, if the library does not protect metatables, any code can get the
> >__gc metamethod and call it explicitly.
> IMHO, protecting the metatable is a good idea anyway so that no-one
> removes the `__gc` metamethod and you run out of resources somewhere
> else.

Someone can trivially hold a reference to the object so that you
run out of resources. There is no need to remove __gc.

> >Second, it is a good practice (well, I think it is) to provide an
> >explicit way to "close" an object that needs finalization.
> >
> >The io library, for instance, does that.
> It's easy for the io library, because it stores pointers. Downside
> is that the garbage collector isn't aware of the extra memory, and
> memory fragmentation could be higher since there are multiple
> allocations for each userdata now. For every non-pointer userdata
> you'd have to add an extra field to indicate the state of
> finalization.

1 bit is not that expensive.

> But now every (meta-)method has to check that the userdata is still
> valid, and most Lua code that uses those (meta-)methods has to check
> again unless it is ok with a simple getter/setter throwing an error.

Most of these methods have to check that the userdata has the correct
type, anyway. It should be easy to bundle together these two tests
(the object has the correct type *and* it is not closed.)

> Also there are cases where explicitly "closing" an object is unsafe,
> e.g. if another object holds a pointer to that object. You can
> ensure the correct `__gc` order by storing references in the
> appropriate uservalue tables, but invalidating dependent objects is
> harder -- especially if the dependencies might change at runtime.
> Concrete examples from the last three libraries I created bindings
> for are renderers and textures in libSDL, memory pools and any other
> APR object in the Apache Portable Runtime library, and
> Fl_Input_Choice and its Fl_Input and Fl_Menu_Button subwidgets in

It is worth remembering that, by using simple tricks with weak tables,
it is not difficult to allow an object to be naturally finalized (that
is, it has its __gc called by the collector) *and* to keep a reference
to it. So, if you are worried about that situation, you need some
kind of extra protection anyway; it is not enough to hide the __gc
from the user. (A better technique in some cases is to hide the
object itself from the user.)

-- Roberto