lua-users home
lua-l archive

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


On, 26 Aug 2013 20:38 Kevin Martin wrote: 
> On 26 Aug 2013, at 15:02, Dominik Zaczkowski wrote:
> 
> > I have problem with userdata and garbage collection, until now I thought that after userdata __gc
> > metamethod is called it means that lua cannot touch my data in any way,
> 
> 
> It doesn't work the way you want it to. imagine if it did, how is the garbage collector supposed to dispose of cyclic data structures. For example, in the below code, A and B are both unreachable, which gc method should be called first?
> 
> local m = {}
> function m.__gc(self)
> 	print(string.format("Garbage Collecting %s, still paired with %s", self.name, self.paired.name)
> end
> 
> do
> 	local A = {name = "A"}
> 	local B = {name = "B"}
> 	
> 	setmetatable(A, m)
> 	setmetatable(B, m)
> 
> 	A.paired = B
> 	B.paired = A
> end
> 
> --A and B both unreachable, but reference each other.
> 
> > How can I be sure that my userdata is gone, and I can free its resources?
> > Only solution that I see is to mark userdata as free on __gc and then check for that it in every
> > function exposed to lua.
> 
> Either that or change the userdata's metatable to one where __index and __newindex both raise errors - that way if any code tries to access it, an error is raised.
> 
> Thanks,
> Kev

Thank you Kevin, now i understand why my data is accessed. But I still don't get how __index and __newindex metamethods could help, my functions exposed to lua are not allways userdata methods - and that was your point, to hide them, right?

I tried to throw lua_error() in my wrapper function which gets the userdata, but sadly i got panic on lua_gc(), changeing userdata metatable also doesn't work, as luaL_userdata idirectly calls lua_error(). I guess only option is to every time check if my ud has been collected.