On 5/18/2012 6:19 AM, Cosmin Apreutesei wrote:
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.
Hmm.. I guess that would be a good way for me to think about them! Thanks for it :)
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