lua-users home
lua-l archive

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


I am assuming that you are interested in lua_ref for some kind of reference
counting mechanism OR to prevent garbage collection for a class of objects
(including Lua functions) and that you are using Lua 5.0;

I am not sure what specific issues that you are facing, but I can tell you
that luaL_ref and luaL_unref by themselves are too low level and you will
have to build a "tiny" layer on top of these functions.

To cut a long story short, some moons ago I wrote a binding to "Austin" and
I was faced with a class of problems that reference counting seemed to
solve. I wrote a "tiny" layer that you may find useful for learning purpose
or on its own merit.

I am not sure if I can attach to a post, so if you want the code send me an
e-mail and I will send it to you and anyone else who may be interested.
Although I had plans to put it on the wiki it is now deferred indefinitely
since the module is named "ldb" which already taken up by another author for
another module and I am not inclined to spend anymore time on it for the
moment.

Here is a brief descriptions of the functions in the "tiny" layer in "C"
that hides the details of luaL_ref and luaL_unref:

/**
* @brief create a reference pool.
*
* Not required to be called explicitly.
*/
void lni_create_ref_pool(lua_State *L, void *pool);

/**
* @brief destroys a reference pool.
*
* Use with extreme caution since all references after
* this function call MAY be collected by GC.
*/
void lni_destroy_ref_pool(lua_State *L, void *pool);

/**
* @brief Returns the reference to the object on the stack at index
*        <si> in <pool>.
*
* <pool> is really a lightuserdata that is used as an index to a
* global (albeit internal) table.
*
* If the object (at stack index 'si') does not exist in the <pool>
* then it is added to the pool, a luaL_ref value is associated and
* the reference count to this newly added object is set to 1. The
* newly luaL_refd value is returned.
*
* If the object exists in the <pool>, then the reference count is
* bumped up and the luaL_ref value associated with this object is
* returned.
*
* @todo need details on how this impacts the garbage collector,
*       memory consumption and the life cycle of these pinned
*       objects.
*/
int lni_ref(lua_State *L, void *pool, int si);

/**
* @brief Returns a positive integer if the object referenced by
*        <lref> in <pool> is unreferenced succesfully from
*        the <pool>.
*
* <pool> is really a lightuserdata that is used as an index to a
* global (albeit internal) table.
*
* If the object does not exist in the <pool> for whatever reason,
* the return value is LUA_NOREF.
*
* If the object exists in the <pool>, then the reference count is
* reduced by 1.
*
* If the reference count counts down to zero, then then the object
* is luaL_unrefd, the record associated with this object is 'nil'd
* and finally the function returns 0. Otherwise the reference count
* is returned.
*
* @todo need details on how this impacts the garbage collector,
*       memory consumption and the life cycle of these pinned
*       objects.
*/
int lni_unref(lua_State *L, void *pool, int lref);

/**
* Put the value pointed to by lref on the top of the stack
*/
void lni_getref(lua_State *L, void *pool, int lref);


/**
* This function was taken from ltablib.c; it would be
* a useful function for debugging, and testing.
*
* Executes the given func over all elements of table.
* For each element, func is called with the index and
* respective value as arguments. If func returns a
* non-nil value, then the loop is broken, and this
* value is returns as the final value of foreach.
*
* The behaviour of foreach is undefined if you change the
* table t during the traversal.
*/
int lni_foreach (lua_State *L, int ti, int fi);



> -----Original Message-----
> From: lua-bounces@bazar2.conectiva.com.br
> [mailto:lua-bounces@bazar2.conectiva.com.br]On Behalf Of Chris Chapman
> Sent: Thursday, November 06, 2003 7:57 AM
> To: lua@bazar2.conectiva.com.br
> Subject: lua_ref problem
>
>
> Okay, I'm having to revisit this problem, because my original
> workaround is
> insufficient for the other issues that have arisen because of
> it. I hope
> someone here can see what I'm doing wrong.
>
> Given the script:
>
> do
> 	function foo()
> 		print("foo\n");
> 	end
>
> 	function bar()
> 		print("bar\n");
> 	end
>
> 	print (GetFunctionReference(foo) .. "\n");
> 	print (GetFunctionReference(foo) .. "\n");
> 	print (GetFunctionReference(bar) .. "\n");
> 	print (GetFunctionReference(foo) .. "\n");
> end
>
> and "GetFunctionReference" being a C function registered with
> lua which
> looks like:
>
> int		GetFunctionReference(lua_State*	L)
> {
> 	//get a reference to the first argument on the stack
>
> 	//check the argument is a lua function
> 	if (lua_type(L, -1) == LUA_TFUNCTION)
> 	{
> 		int		iReference	=	lua_ref(L, 1);
> //1 indicates a locked reference
>
> 		//return the reference index as a number
> 		lua_pushnumber(L, iReference);
> 		return 1;
> 	}
> 	else
> 	{
> 		return 0;
> 	}
> }
>
> Running this script produces the output:
>
> 3
> 3
> 3
> 3
>
> I.e. no matter what I try to pass to lua_ref, I always get 3 back as a
> reference. Breakpointing the C code indicates that it is
> indeed 3 being
> returned from lua_ref each time. Tracing the lua code follows
> the same path
> each call.
>
> Again, this is a difference between 4.0.1 and 5.0.
>
> Thanks
> ChrisC
>