lua-users home
lua-l archive

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


On May 21, 2014, at 3:07 PM, Philipp Janda <siffiejoe@gmx.net> wrote:
> 
> It's not just two objects where one depends on the other, but N objects which depend on one other. E.g. in APR you have memory pools that do all the allocation/deallocation of APR objects (files, directories, processes, strings, sockets, etc.), and destroying the pool will destroy all APR objects created with it. The same is true for textures (chunks of memory in video RAM) and renderers in SDL: The renderer destroys all textures that belong to it when it is destroyed, so you must not finalize the renderer before its textures or you will double-free the textures (or crash trying).
> I also use the finalizer ordering to make sure that `APR_terminate`/`SDL_Quit` is called after all objects from those libraries are destroyed by putting a userdata with a suitable `__gc` in the registry before I initialize the library.
> Lua itself uses a similar mechanism to ensure that shared libraries are unloaded after all userdata objects using symbols from those libraries are finalized.
> 

Completely agree that this is a messy problem. It’s just if it was me I’d be very wary of relying on finalizer ordering to solve it, unless the official Lua docs had very strong guarantees about that (and even then I’d still avoid it as much as I possibly could).

As others have said, pretty much the only way you can tackle this is using weak tables and/or having idempotent finalizers that may be called by the GC or by other parts of the system as necessary.

—Tim