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 17:42:28 +0800

2012/7/19 Mike Pall <mike-1207@xxxxxxxxxx>:
> Johnson Lin wrote:
>> Since anonymous FFI callbacks are anchored permanently, and explicitly
>> call cb:free() every time is pretty troublesome too, is it considered
>> good to do this?
>>
>> local cb = ffi.gc(ffi.cast("CALLBACK", function() end), function(self)
>> self:free() end)
>>
>> cb()
>> cb = nil
>> collectgarbage("collect")
>>
>> I did print some messages in the callback body and the finalizer body
>> to verify it's working.
>
> 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
>

Hello, thanks for the tip,

However since my use case is actually like classic UI script where I
register callbacks from Lua to C, I guess I'll have to do cb:free()
manually in the UI object's finalizer..

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

Other related posts: