Re: ffi: callback lifetime

  • From: Cosmin Apreutesei <cosmin.apreutesei@xxxxxxxxx>
  • To: luajit@xxxxxxxxxxxxx
  • Date: Fri, 18 May 2012 16:19:43 +0300

Thanks, for the explanation.

I did read the docs, I guess the phrase "Callbacks due to implicit
conversions are permanent!" got me thinking what kind of callbacks
aren't permanent.

Now I picture them like file handles, in that there's a finite number
of them and I must free them manually, except file handlers also have
a __gc which is not very useful anyway with a non-deterministic
collector.

On Fri, May 18, 2012 at 3:46 PM, Mike Pall <mike-1205@xxxxxxxxxx> wrote:
> Cosmin Apreutesei wrote:
>> AFAIU implicit callback objects created by assigning a Lua function to
>> a function pointer are internally anchored along with the Lua function
>> and there's no way to access them or free them (or the Lua function).
>> But callbacks created by ffi.cast() are not anchored and thus subject
>> to normal garbage collection rules, and thus no need to "unanchor"
>> them by cb:free(), is that right?
>
> No, there's no difference between these. Callbacks are always
> anchored independently and managed manually. That's why you need
> to explicitly free them.
>
> The only difference is that with implicit conversions, you can't
> catch the callback function pointer in a variable, so you'll have
> a hard time calling cb:free() on it. In other words: only the
> explicit conversion with ffi.cast() allows you to free the
> callback. Otherwise it'll never be freed (until the lua_close()).
>
>> So if I pass some_lua_function where a function pointer is expected,
>> the callback is permanent, but if I pass ffi.cast('WNDPROC',
>> some_lua_function) the callback is only guaranteed to last until the
>> function returns, and will be freed on the next gc cycle without me
>> having to cb:free() it, right? Or do I always have to manually
>> cb:free() it afterwards if I don't need it ? In other words, does a cb
>> object have a __gc that does self:free() ?
>
> Nope. Callbacks are never subject to GC. That's because in general
> the VM cannot tell how long the C side may hold onto the callback
> address. But you can tell -- by reading the docs. :-)
>
> An allocated callback keeps the callback slot alive (there's a
> limited number of these) as well as the Lua closure. If you free
> the callback, the slot is immediately available again and the Lua
> closure is now subject to regular GC (depends on whether it's
> anchored somewhere else, too).
>
> --Mike
>

Other related posts: