lua-users home
lua-l archive

GC: Island-like with the registry

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


Hi,
I've a got a problem right now, and I wonder how I can fix it.
Let me expose you.
I've a type of object that we will call `ninja' (because ninjas
are cool).
Each `ninja' has a weapon: a callback function!
So basically I get a struct defined as:
typedef struct ninja_t {
 int weapon;
} ninja_t;
So far so good. Now, when I give a weapon (function) to a ninja, I do:
myninja->weapon = luaL_ref(L, LUA_REGISTRYINDEX);
That set myninja->weapon to a reference number in the registry.
Now, as you know, ninja get killed often, so I store them in a
weak-keyed table:
battles = setmetatable({}, { __mode 'k' })
In the `battles' table, I will store a `mutant' as the key, and a ninja
has the value (we all know that ninja fight mutants).
battles[mymutant] = myninja
So far, so good: as soon as `mymutant' get killed, since it's a
weak-keyed table, myninja will get unref'ed.
BUT.
Now imagine I add a weapon to myninja and then store it:
myninja.weapon = function () kick_ass_of(mymutant) end
battles[mymutant] = myninja
Now, I've something which is like an "island" and will be never garbage
collected. Why? As I understand, that's because myninja.weapon reference
`mymutant'. But, since it's a function stored in the Lua registry, Lua
has no clue that this function is used and store for `myninja'. So it
basically thinks that mymutant has a valid reference.
Schematic:
 From my programmer's point of view:
battles[mymutant] --ref--> myninja --ref--> weapon
 ^----------------ref------------------------'
 Cyclic ref, but Lua is smart so can collect.
 From real Lua point of view
REGISTRY battles[mymutant]
 \ /
 \ /
 \ ref ref /
 \ /
 `-> mymutant myninja
 Uncollectable: mymutant is refed by the callback function (weapon)
 of the ninja in a table (registry), so no reason to kill
 battles[mymutant].
I clearly need to tell Lua: "hey buddy, I'm storing things in the
registry for `myninja', so don't think it's totally unrelated".
I am not sure I can do that.
What's the solution guys?
Cheers,
-- 
Julien Danjou
// ᐰ <julien@danjou.info> http://julien.danjou.info
// 9A0D 5FD9 EB42 22F6 8974 C95C A462 B51E C2FE E5CD
// Don't give up.

Attachment: signature.asc
Description: Digital signature


AltStyle によって変換されたページ (->オリジナル) /