lua-users home
lua-l archive

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


I have a question about providing Lua callbacks from a wrapped C library that seems to have never been fully answered (at least I can't find the thread). I am hoping someone can offer a recommended approach for this problem.

In general, when I've wrapped 'C' libraries with Lua there are invariably callback functions that need to be handled as well. For the sake of this discussion I am assuming the 'C' callback is delivered on the same OS thread on which the main Lua state has been initialized in. Let's say (from Lua) the callback registration looks like the following:

registerCallback(function(event)
    print("The event is:" .. event)
end)

The 'registerCallback' function is implemented in a 'C' module. This function will receive a Lua state (L) and the anonymous Lua callback function on the Lua stack. Now, I understand that I must "anchor" the Lua callback function so that the garbage collector will not dispose of this anonymous function before my 'C' callback code can delegate the handling of the event to the Lua callback code. I typically anchor it by adding a reference to it in the registry:

int r = luaL_ref(L, LUA_REGISTRYINDEX);

The reference (r) is saved so that when the 'C' callback routine is eventually called the corresponding Lua callback function can be retrieved and called. After the Lua callback is called then this function is unreferenced so that it's available for garbage collection by the VM.

What I'm really concerned about is the Lua state/thread (L). Does the Lua thread (L) need to be anchored as well so that it won't be collected while we're waiting for the callback to occur? I know (L) in this instance embodies both a Lua state and an associated Lua thread/coroutine. I suspect I don't need to be concerned about the Lua "state" part being collected (because that is the context in which the code is running) but I'm nervous about the Lua thread. If the above Lua code had been executed within a coroutine (other than the one-and-only main thread) and afterwards the coroutine exited, I believe this Lua thread is available for collection by the GC. What happens when my 'C' callback returns and I try to use the saved Lua state (L) (saved only as a C pointer) to call the Lua callback with lua_call(L, nargs, nresults). If the Lua coroutine thread has been collected,  on whose Lua thread is the Lua callback executed?

To summarize my question:

1) Do I need to somehow anchor my Lua state (L) so that the future 'C' callback has a valid Lua state (and thread) to call back into? If I do need to anchor the Lua state, how do I do this?

2) Do I need to be concerned with the Lua thread that the callback is executed on when I call it from 'C' via the lua_call() function? Do I need to explicitly (somehow) anchor this Lua thread/coroutine?

I hope someone can clear this mystery up for me. I've always had an uneasy feeling about this topic and I suspect other implementations I've looked at may have made some bad assumptions as well.

Any pointers from the Lua gurus would be greatly appreciated.