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 >