lua-users home
lua-l archive

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


Am 22.05.2014 07:41 schröbte Tim Hill:

On May 21, 2014, at 9:03 PM, Philipp Janda <siffiejoe@gmx.net> wrote:

I don't think that anyone has mentioned this yet, but I guess you mean something like this:
*   put B in A's uservalue table to keep it alive as long as A is alive
*   put a weak back reference to A in B's uservalue table
*   in A's finalizer free A if it hasn't been freed before by someone else
*   in B's finalizer first free A if the weak back reference still exists and A hasn't been freed before, and then free B itself if it hasn't been freed before

But this (if it actually works) relies on undocumented order of clearing objects from weak tables in relation to calling finalizers of other objects in the same gc cycle. (In Lua 5.2 you can use weak values which have the necessary guarantees, and in Lua 5.1 you can probably use strong back references with some degradation of lifetime granularity.)
And of course my `SDL_Quit` finalizer would store references to all SDL objects ever created, but this approach could still be an option for the OP ...

Note quite. You can have STRONG references from A to B and B to A.
This won’t stop the GC doing it’s job since as soon as both A and B
are unreachable they will be collected (the circular references don’t
impact the ability of the GC to identify A and B as garbage).

Yes, that's exactly what I meant with degradation of lifetime granularity. On Lua 5.2 a weak-valued field keeps the reference until the finalizer has run which is what you need, it's just Lua 5.1 that is underspecified in this regard ...

It’s then a simple matter to have A call B’s finalizer before it does
its own finalization, ensuring B is always done first, assuming of
course that’s B’s finalizer is idempotent. This pattern will always
work regardless of the behavior of the GC. This can even be
generalized by having A maintain a table of references to many B’s.

So in the case of my `SDL_Quit` finalizer, it keeps all other SDL objects alive until `lua_close` ...


—Tim


Philipp