Equality vs. Identity of userdata?

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

Equality vs. Identity of userdata?

Stephan Herrmann-2
Hi,

What exactly is the behaviour of lua_pushusertag(u,t) ?
I experience it to create a new lua object of type userdata only
once for each value of u. Is this behaviour part of the specification,
or implementation detail? Are two _equal_ userdata objects in Lua
always _identical_??

The reason for asking is reference-counting and garbage collection.
I have a C datastructure containing a reference-count and I wanted to
use the same count for references both from C and from Lua. So my
idea was, every time I "export" a C-object to Lua (using lua-pushusertag),
I increment the reference-count. Then I have a "gc" tagmethod, which
calls a free routine that decrements the ref-count and if 0 is reached
frees my resources. So it is transparent, who keeps references
to an object. Whenever the last ref is removed, the object is really freed.

>From my experience I would have to keep two ref-"counts": one for C and 
a boolean "count" for Lua, because a userdata seems to be referenced at 
most once from Lua. The reverse conclusion seems to be, that two calls
to lua_pushusertag(u,t) with the same u entail at most one call to the
"gc" tagmethod. Is this correct?

A convenient solution would be, if I knew whether lua_pushusertag
created a new object or recycled an existing one. Only in the first
case I would increment my ref-count.


Stephan

Reply | Threaded
Open this post in threaded view
|

Re: Equality vs. Identity of userdata?

Roberto Ierusalimschy
> What exactly is the behaviour of lua_pushusertag(u,t) ?

For userdata, equality is identity.
If there is a userdata u with tag t in the Lua environment,
this same object is reused when you push it again.
That is, there is only one copy of
equal objects in the environment. If you want to do reference-count,
all you need is a boolean. When you push an object (void *) into
Lua, set the boolean to true. When Lua calls the gc fallback, set
the boolean to false: It means Lua has no more any reference to this
specific userdata.

-- Roberto