lua-users home
lua-l archive

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


> In your `A.__gc()` metamethod add the A userdata to a global table and
remove its metatable (to prevent `__gc()` from being called again in Lua
5.3). Then remove the A userdata from that table when C is called.

That seems like something that might work. Let's see if I understood correctly: If I create a reference to "A" (in the registry, for example) while its __gc method is being called, I'm effectively stopping lua from finishing the garbage collection process right? Is this how Lua 5.1 and later works?

On Thu, Nov 19, 2015 at 3:31 PM Philipp Janda <siffiejoe@gmx.net> wrote:
Am 19.11.2015 um 15:28 schröbte Thiago Padilha:
> Consider the following scenario:
>
> I have a userdata "A" being referenced referenced by another userdata "B".
> "A" has the __gc metamethod that can be used to schedule its removal from
> "B", but note that the reference is not removed immediately, it is deferred
> until a certain function "C" is called(This is how the library I'm working
> with behaves). The problem is that if Lua frees "A" memory before "C" is
> called, "B" will be left with a dangling pointer that can cause memory
> errors when "C" is called later(It will be called for sure).
>
> What I want to achieve is to defer "A" memory from being freed until C is
> called. Is there a way to do this? I know that one option is to work with
> userdata that simply references "A" and take care of freeing memory myself,
> but I'd rather avoid this because it would need a lot of refactoring in the
> project I'm working on.
>

This is probably your best option if the C call could happen after
`lua_close()` because all memory allocated by Lua is released at that point.

If you can rule that situation out:
In your `A.__gc()` metamethod add the A userdata to a global table and
remove its metatable (to prevent `__gc()` from being called again in Lua
5.3). Then remove the A userdata from that table when C is called.

HTH,
Philipp