Garbage collection of userdata

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Garbage collection of userdata

Paul Chiusano-3
Hi,

This is probably a simple question. I'm working on a simple numeric
vector class, and I'd like to be able to create 'views' of these
vectors which don't require making a copy of the original vector, aka:

a = numvector.new(100) -- initialize a vector w/ 100 elements, zeroed out
b = a:view(4,10)  -- create a view which shares the same memory block as 'a'
b[1] = 42  -- a sees this change: so now a[4]==42

On the C side, I have this:

typedef struct NumVector {
        unsigned int start, stop;
        lua_Number *values;
} NumVector;

So, in creating a new 'view', the newly created object will have the
same values array, but with possibly different values for 'start' and
'stop'.

If I were to just allocate a NumVector with a block, like:

/* unsigned int size = something */
NumVector *a = (NumVector *)lua_newuserdata(L, sizeof(NumVector) +
size*sizeof(lua_Number));

...then 'a' would be subject to garbage collection by Lua. Great!
Except that when a becomes garbage, its values array will be
deallocated, so any views that point to it will now be invalid. I
could allocate the values array separately:

NumVector *a = (NumVector *)lua_newuserdata(L, sizeof(NumVector));
a->values = (lua_Number *)lua_newuserdata(L, size*sizeof(lua_Number));

but I don't think this is correct. I'd imagine Lua could immediately
collect a->values since nothing on the Lua side will point to it. (or
does the mark and sweep follow references on the C side, too?). What
would be the cannonical way to handle this situation?

-Paul
Reply | Threaded
Open this post in threaded view
|

Re: Garbage collection of userdata

Michael Broughton
If you are using Lua 5.1, my suggestion would be to store a reference in
the environment table of each 'view' userdata, to its parent 'vector'.
This reference will prevent Lua from collecting a 'vector' before all of
its 'views' have been collected.

If you are using Lua 5.0 you will have to find another way. Check out
PIL for some examples.


Mike



Paul Chiusano wrote:

> Hi,
>
> This is probably a simple question. I'm working on a simple numeric
> vector class, and I'd like to be able to create 'views' of these
> vectors which don't require making a copy of the original vector, aka:
>
> a = numvector.new(100) -- initialize a vector w/ 100 elements, zeroed out
> b = a:view(4,10)  -- create a view which shares the same memory block
> as 'a'
> b[1] = 42  -- a sees this change: so now a[4]==42
>
> On the C side, I have this:
>
> typedef struct NumVector {
>     unsigned int start, stop;
>     lua_Number *values;
> } NumVector;
>
> So, in creating a new 'view', the newly created object will have the
> same values array, but with possibly different values for 'start' and
> 'stop'.
>
> If I were to just allocate a NumVector with a block, like:
>
> /* unsigned int size = something */
> NumVector *a = (NumVector *)lua_newuserdata(L, sizeof(NumVector) +
> size*sizeof(lua_Number));
>
> ...then 'a' would be subject to garbage collection by Lua. Great!
> Except that when a becomes garbage, its values array will be
> deallocated, so any views that point to it will now be invalid. I
> could allocate the values array separately:
>
> NumVector *a = (NumVector *)lua_newuserdata(L, sizeof(NumVector));
> a->values = (lua_Number *)lua_newuserdata(L, size*sizeof(lua_Number));
>
> but I don't think this is correct. I'd imagine Lua could immediately
> collect a->values since nothing on the Lua side will point to it. (or
> does the mark and sweep follow references on the C side, too?). What
> would be the cannonical way to handle this situation?
>
> -Paul
>