lua-users home
lua-l archive

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


On Wed, Feb 21, 2007 at 09:02:19AM -0800, Wesley Smith wrote:
> Currently, I'm doing instance counting and call lua_newuserdata()
> whenever I want to push copies of a userdata into Lua.  When __gc is
> called, I check how many instances of it exist and free it only when
> the one being deleted will result in a count of 0.

> To break the problem down a bit more, if I copy userdata from the Lua
> side, Lua takes care of instance counting, but in my case, I'm copying
> userdata from the C side and I am doing the instance counting.  My
> userdata is boxed pointers and I'm wondering if there's anything to be
> gained from keeping track of the handle to my userdata the Lua uses
> and the pointer to the data that the C library functions actually use
> such that when I get the data pointer, I can look up its Lua handle in
> a table and push that instead of calling lua_newuserdata()?  Is there
> a way I can give lua a userdata pointer and somehow get the variable
> to the top of the stack so that I can return it from a C function,
> effectively doing the copy in Lua, causing Lua to do instance counting
> for me?

You can use lightuserdata and weak tables to do this. As a sketch:

- Keep a table in lua that has weak values, and that maps lightuserdata
  to userdata.
- When you have a C pointer that you want to create a userdata for,
  create a lightuserdata of it, and look the lightuserdata up in the
  table. If its there, use the value of that key, if its not, create
  a userdata.
- When the __gc metamethod gets called for one of your userdata you know
  that no lua code has a reference to it anymore and that lua removed
  the key/value pair from your table, and now you can free the C
  resources it refers to.

Is that kind of what you were looking for? You can get more info on
lightuserdata and the __mode of a table in the PIL and lua5.1 ref
manual.

Sam