Re: Making FFI callbacks call free() automatically when it's collected

  • From: Johnson Lin <arch.jslin@xxxxxxxxx>
  • To: luajit@xxxxxxxxxxxxx
  • Date: Thu, 19 Jul 2012 19:32:53 +0800

2012/7/19 Johnson Lin <arch.jslin@xxxxxxxxx>:
> 2012/7/19 Mike Pall <mike-1207@xxxxxxxxxx>:
>> This works. But the time when the GC gets around to collect the
>> callback slot is not predictable. Since the slots are a scarce
>> resource, you may run out of them.
>> You need know the exact point in time when the callback is no
>> longer used, anyway. IMHO it's better to create a convenience
>> wrapper:
>> local function wrap_iter(func)
>>   local cb = ffi.cast("CALLBACK", func)
>>   iter(cb)
>>   cb:free()
>> end
>> wrap_iter(function() end)
>> --Mike
> I was hoping that by using a weak-key obj -> callbacks mapping table,
> all the callbacks related to that UI object will get destructed when
> the UI object itself get collected. But since there's a lot different
> kinds of UI events there, I'd have to write quite a few additional
> lines in the UI object's finalizer. Guess I was too lazy..
> best,
> Johnson

Well, I must be wrong or just too stupid,

It turned out that I can't even write a finalizer to clean up the
callbacks related to my UI objects.

I was tracking all the callbacks with a weak-key obj-to-callbacks
mapping table, since all my UI objects are really cdata from the FFI,
I can't just add property to them to hold refs to the callbacks in

I thought adding a few lines to traverse the tracking table and call
cb:free() when the UI objects get collected should be easy enough,
BUT, somehow, due to the weak-key property of the mapping table I
guess, when the finalizer of the object was called, that record in the
table was already gone! So it couldn't call cb:free() at all....

That's really strange though, since the finalizer of the object hasn't
actually returned yet, there should still be a ref in the Lua VM to
the object, no? How come the weak-key table can lost track of that


Other related posts: