lua-users home
lua-l archive

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


Hi all,

I have a small question that should not make people angry :-)

Recently I'm writing a lot of library C code for Lua and I've got the
need of something tha Lua seems to lack: userdata cross-references.

I will try to explain my idea. Let suppose that an userdata of type A
allocate internally some resources that will be freed only when the
object will be garbage-collected with the __gc metamethods. Let use
suppose that I want to create another type of userdata, let's say of
type B, that make reference to some resources allocated by an object
of the type A. This scenario pose a problem because is the object of
type A is garbage-collected when the object of type B is still alive
it will raise some serious errors.

For me this features will be very useful to create lightweight object
that points to the resources owned by other objects without the needs
of creating unnecessary copies of the data.

As far as I know there is no obvious solution to this problem but I
would like to check with more expert people here.

One solution could be to create a Lua table that embed the object of
type B and keep a reference to the object of type A so that this
latter will not be freed. This solution is functional but cumbersome
because force you to create a Lua table to wrap your object and to
attach a metatable to the table instead of to your userdata itself.

I was thinking that it would be nice if the userdata could store one
or more reference to other userdata objects in order to ensure that
the GC does not free the main object that own the resource if other
objects that need the same resource are still alive. In my idea the C
API could be something like:

/* let us suppose that in stack position 'index' we have a userdata of type A */
struct b *bobj = lua_newuserdata(sizeof(struct b));
lua_adduserdataref (L, index); /* add to userdata on top of the stack
a reference to userdata at 'index' */
/* and keep the stack unchanged */

This kind of feature could be implemented by adding an extra space of
dimension to keep a pointer at the end of the userdata. If there are
no references this pointer will be null or otherwise it will point to
a linked list of references to Lua objects (userdata). Then the GC
should check the userdata cross-references just the same as it checks
for cross-references between ordinary Lua tables.

Does this make sense ? Is there a more simple/obvious solution to my problem ?

In my experience the kind of feature I propose would be a big plus to
simplify my library code by eliminating some boiler-plate solutions I
was forced to adopt.

Francesco