Search code examples
multithreadinglualua-lanes

LuaLanes Unable to pass global variables between functions (in a single lane)


hope you're having a good day.

I have been programming a IRC chatbot in Lua the past few days, and finally I want to start implementing multiple server support into it.

So far, I have created the irc "object" to manage each server, and all that happy stuff - Now, I am having problems with threading.

Lua, as you probably know, doesn't have thread support built-in. LuaLanes and LuaThreads seemed like the closest to what I wanted to use, in terms of libraries. What made me choose LuaLanes is because LuaThreads requires a modified lua core. Plus the "lindas" feature of LuaLanes caught my eye (for later use in plugins)

Anyway, the issue that I'm having is when you generate a lane using function middleman (for example), which then calls another function sqr (for example). if you generate the function like lanes.gen({globals = _G}, middleman), middleman will have access to everything in your current global scope, which is exactly what I want. The problem is, if middleman calls sqr, and sqr uses something from the global scope, it throws an error, almost as if _G suddenly became empty.

Here's some example code I managed to throw together, using my example above:

require 'lanes'

function sqr()
    print(5*5)
end

function middleman()
    sqr()
end

gen = lanes.gen({globals = _G}, middleman)

print(gen()[1])

Produces an error saying:

tc@box:~$ lua lanestrouble.lua 
lua: lanestrouble.lua:4: attempt to call global 'print' (a nil value)
stack traceback:
        [C]: in function 'error'
        ./lanes.lua:190: in function <./lanes.lua:136>
        lanestrouble.lua:13: in main chunk
        [C]: ?
threading.c 399: pthread_cond_destroy(ref) failed, 16 EBUSY
Aborted
tc@box:~$ 

(By the way, I'm using linux)

However, if you change line 11 from gen = lanes.gen({globals = _G}, middleman) to gen = lanes.gen({globals = _G}, sqr), it works fine.

I've checked, and the same thing happens if you pass "*" (or any other option for the "libs_str" parameter) to load the default libraries.

I really wish there was something like Java's threading library for Lua, that's how I originally learned to use threads. (I know, not the most ideal environment I suppose)

Thanks, I appreciate help a lot. Especially since this has completely halted my IRC bot development! :(


Solution

  • Making sqr local does the trick. Since it becomes an upvalue of middleman, it is copied to the new lane.

    require 'lanes'
    
    local function sqr()
        print(5*5)
    end
    
    function middleman()
        sqr()
    end
    
    gen = lanes.gen({globals = _G}, middleman)
    
    print(gen()[1])
    

    But definitely something strange is going on. I mean, even when passing explictly "sqr" and "print" to the new lane, it won't see "print" (when called by "sqr"). It seems to me that something is not working right when serializing functions between lanes. You should contact its maintainer.