lua-llthreads icon indicating copy to clipboard operation
lua-llthreads copied to clipboard

implement lua wrapper like in zthreads

Open moteus opened this issue 13 years ago • 1 comments

I find useful this module: (note: new thread call lua_init from env.)

local llthreads = require"llthreads"

local setmetatable = setmetatable
local tonumber = tonumber
local assert = assert

local thread_mt = {}
thread_mt.__index = thread_mt

function thread_mt:start(detached)
    return self.thread:start(detached)
end

function thread_mt:join(...)
    return self.thread:join(...)
end

function thread_mt:kill()
    return self.thread:kill()
end

local bootstrap_pre = [[
local action, action_arg = ...
local lua_init = os.getenv("lua_init")
if lua_init and #lua_init > 0 then
    if lua_init:sub(1,1) == '@' then
        dofile(lua_init:sub(2))
    else
        assert(loadstring(lua_init))()
    end
end

-- create global 'arg'
arg = { select(3, ...) }
]]

local bootstrap_post = [[
local func
-- load Lua code.
if action == 'runfile' then
    func = assert(loadfile(action_arg))
    -- script name
    arg[0] = action_arg
elseif action == 'runstring' then
    func = assert(loadstring(action_arg))
    -- fake script name
    arg[0] = '=(loadstring)'
end

-- run loaded code.
return func(unpack(arg))
]]

local bootstrap_code = bootstrap_pre..bootstrap_post

local function new_thread(bootstrap_code, action, action_arg, ...)
    local thread = llthreads.new(bootstrap_code, action, action_arg, ...)
    return setmetatable({
        thread = thread,
    }, thread_mt)
end

local M = {}

M.set_bootstrap_prelude = function (code)
    bootstrap_code = bootstrap_pre .. code .. bootstrap_post
end;

M.runfile = function (file, ...)
    return new_thread(bootstrap_code, 'runfile', file, ...)
end;

M.runstring = function (code, ...)
    return new_thread(bootstrap_code, 'runstring', code, ...)
end;

M.runfile_ex = function (prelude, file, ...)
    local bootstrap_code = bootstrap_pre .. prelude .. bootstrap_post
    return new_thread(bootstrap_code, 'runfile', file, ...)
end;

M.runstring_ex = function (prelude, code, ...)
    local bootstrap_code = bootstrap_pre .. prelude .. bootstrap_post
    return new_thread(bootstrap_code, 'runstring', code, ...)
end;

return M

And zthreads implement:

local zmq = require"zmq"
local Threads = require"llthreads.ex"

local zthreads_prelude = [[
local zmq = require"zmq"
local zthreads = require"zmq.threads"
local parent_ctx = arg[1]
if parent_ctx then zthreads.set_parent_ctx(zmq.init_ctx(parent_ctx)) end
arg = { select(2, unpack(arg)) }
]]

module(...)

function runfile(ctx, file, ...)
    -- convert ZMQ_Ctx to lightuserdata.
    if ctx then ctx = ctx:lightuserdata() end
    return Threads.runfile_ex(zthreads_prelude, file, ctx, ...)
end

function runstring(ctx, code, ...)
    -- convert ZMQ_Ctx to lightuserdata.
    if ctx then ctx = ctx:lightuserdata() end

    return Threads.runstring_ex(zthreads_prelude, code, ctx, ...)
end

local parent_ctx = nil
function set_parent_ctx(ctx)
    parent_ctx = ctx
end

function get_parent_ctx(ctx)
    return parent_ctx
end

moteus avatar Aug 13 '12 14:08 moteus

I will look into improving the API for llthreads.

Neopallium avatar Oct 16 '12 08:10 Neopallium