Search code examples
cmultithreadingapilualua-lanes

How can I get the globals or environment from the main state to a Lua lane?


local lanes = require "lanes".configure()
local linda = lanes.linda()
local thread = lanes.gen({globals = _G}, function()
print("Starting thread...")
while true do
    local command = linda:receive("cmd")
    if command=="quit" then
        break
    else
        broadcast(-1,"Hello from lanes.")
    end
end
end)

local threads = {}
local NCORES = 2
for i=1,NCORES do threads[i] = thread() end
linda:send("cmd", "test")
for i=1,NCORES do linda:send("cmd", "quit") end
for i=1,NCORES do threads[i]:join() end

As a test on my game server to get Lua Lanes running properly, I am trying to use a global function from the main state in a new thread. Unfortunately this particular code keeps resulting in an Assert Failure in tools.c line 1216. I'm trying to set this up so I can do busy work without locking up the main thread, and ultimately my game server. Is there a better way to do this perhaps? Or maybe I could run my scripts via luaL_newthread(state) in my server? Please advise me in the right direction as this is currently halting my development. Thanks in advance.


Solution

  • You should not access globals like that in a lane. The thread is run in a separate state. What you get is a deep copy of the globals table (not a reference). Also, by calling a global function in a separate thread you are risking synchronization issues.

    What you can do is to require a module in the thread itself. To get the broadcast function into the thread, you have these options:

    1. Put broadcast and other functions into a module and call require in the thread.
    2. Store broadcast as a local before the thread function to get it as an upvalue.

    Update: unfortunately the second way does not work as it used to anymore. Due to compatibility issues with LuaJIT 2, Lanes has to compute a mapping table of native functions at the time configure is run. I have not found a way to transfer a simple C function into the thread other way than to actually require the module in the thread.