lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Thanks everyone for your input. I've used these ideas to improve my
hotkey implementation:

https://github.com/sdegutis/hydra/blob/next/Hydra/API/hotkey.m

On Mon, Jul 14, 2014 at 4:45 PM, William Ahern
<william@25thandclement.com> wrote:
> On Mon, Jul 14, 2014 at 07:59:53PM +0000, Thijs Schreijer wrote:
>>
>>
>> > -----Original Message-----
>> > From: lua-l-bounces@lists.lua.org [mailto:lua-l-bounces@lists.lua.org] On
>> > Behalf Of Steven Degutis
>> > Sent: maandag 14 juli 2014 17:52
>> > To: Lua mailing list
>> > Subject: How do you usually mix Lua and C callbacks?
>> >
>> > I've got some C functions that take callback which has a void* pointer
>> > for programmer-use. The technique I've been using is making a little
>> > struct that holds the lua_State* and an int, which I store the return
>> > value of luaL_ref'ing the given function. Then inside the C callback,
>> > I take the Lua state and lua_rawgeti the function out of
>> > LUA_REGISTRYINDEX, and call it.
>> >
>> > But this seems very cumbersome and awkward. (Plus it means my function
>> > won't be garbage-collected until I luaL_unref it out of there, but I'm
>> > not sure that can be solved without making use of an explicit
>> > "unregister" method for this C callback). Is there a better way to do
>> > this that is less cumbersome and awkward? Thanks.
>> >
>> > -Steven
>>
>> If your application is not multithreaded, the reference can be stored in a
>> global variable, and the lua pieces can remain on the stack.
>>
>> If you do have a multithreaded environment, then I don't know simpler
>> solutions
>>
>
> That won't work for system-level multithreading, _nor_ for coroutine based
> multithreading where multiple callbacks could be outstanding (e.g. with an
> event loop). The latter is far more common and if the callback is triggered
> from a reuseable module should probably be taken into account (either
> support it or throw an error on concurrent requests) lest somebody get
> burned.
>
> As long as a callback is outstanding one would want the reference to be
> pinned in memory anyhow, regardless of what's happening in Lua-space.
> There's nothing awkward about this.
>
> But if the callback is cancelable and one wanted to integrate this into the
> GC to detect when a callback will go unused--the coroutine or object is
> garbage collected before the callback completes--they could use the specific
> coroutine in, or object on which the method was called as a key in a weak
> table** in the registry. Then from some __gc handler (which handler depends
> on how you anchor it in the weak table) one could cancel the request so a
> callback doesn't try to re-enter Lua using an invalid state context.
>
> ** Preferably a Lua 5.2+ ephemeron table in case the coroutine or userdata's
> uservalue has a problematic reference cycle.
>