From f0a6754cd15912de529b9662e3e08bfaadd6bf1e Mon Sep 17 00:00:00 2001 From: Alexey Melnichuk Date: Mon, 23 Jun 2014 09:40:01 +0500 Subject: Add. `llthreads2.ex` module. --- src/lua/llthreads2/ex.lua | 152 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 152 insertions(+) create mode 100644 src/lua/llthreads2/ex.lua (limited to 'src/lua/llthreads2') diff --git a/src/lua/llthreads2/ex.lua b/src/lua/llthreads2/ex.lua new file mode 100644 index 0000000..26e1a46 --- /dev/null +++ b/src/lua/llthreads2/ex.lua @@ -0,0 +1,152 @@ +-- +-- wraps the low-level threads object. +-- + +-- +-- Note! Define this function prior all `local` definitions +-- to prevent use upvalue by accident +-- +local bootstrap_code = require"string".dump(function(lua_init, prelude, code, ...) + local loadstring = loadstring or load + local unpack = table.unpack or unpack + + local function load_src(str) + local f, n + if str:sub(1,1) == '@' then + n = str:sub(2) + f = assert(loadfile(n)) + else + n = '=(loadstring)' + f = assert(loadstring(str)) + end + return f, n + end + + local function pack_n(...) + return { n = select("#", ...), ... } + end + + local function unpack_n(t) + return unpack(t, 1, t.n) + end + + if lua_init and #lua_init > 0 then + local init = load_src(lua_init) + init() + end + + local args + + if prelude and #prelude > 0 then + prelude = load_src(prelude) + args = pack_n(prelude(...)) + else + args = pack_n(...) + end + + local func + func, args[0] = load_src(code) + + _G.arg = args + arg = args + + return func(unpack_n(args)) +end) + +local ok, llthreads = pcall(require, "llthreads2") +if not ok then llthreads = require"llthreads" end + +local os = require"os" +local string = require"string" +local table = require"table" + +local setmetatable, tonumber, assert = setmetatable, tonumber, assert + +------------------------------------------------------------------------------- +local LUA_INIT = "LUA_INIT" do + +local lua_version_t +local function lua_version() + if not lua_version_t then + local version = assert(_G._VERSION) + local maj,min = version:match("^Lua (%d+)%.(%d+)$") + if maj then lua_version_t = {tonumber(maj),tonumber(min)} + elseif not math.mod then lua_version_t = {5,2} + elseif table.pack and not pack then lua_version_t = {5,2} + else lua_version_t = {5,2} end + end + return lua_version_t[1], lua_version_t[2] +end + +local LUA_MAJOR, LUA_MINOR = lua_version() +local IS_LUA_51 = (LUA_MAJOR == 5) and (LUA_MINOR == 1) + +local LUA_INIT_VER +if not IS_LUA_51 then + LUA_INIT_VER = LUA_INIT .. "_" .. LUA_MAJOR .. "_" .. LUA_MINOR +end + +LUA_INIT = LUA_INIT_VER and os.getenv( LUA_INIT_VER ) or os.getenv( LUA_INIT ) or "" + +end +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +local thread_mt = {} do +thread_mt.__index = thread_mt + +function thread_mt:start(...) + local ok, err = self.thread:start(...) + if not ok then return nil, err end + return self +end + +function thread_mt:join(...) + return self.thread:join(...) +end + +function thread_mt:alive() + return self.thread:alive() +end + +end +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +local threads = {} do + +local function new_thread(prelude, lua_init, code, ...) + if type(lua_init) == "function" then + lua_init = string.dump(lua_init) + end + + if type(prelude) == "function" then + prelude = string.dump(prelude) + end + + if type(code) == "function" then + code = string.dump(code) + end + + local thread = llthreads.new(bootstrap_code, lua_init, prelude, code, ...) + return setmetatable({ + thread = thread, + }, thread_mt) +end + +threads.new = function (code, ...) + assert(code) + + if type(code) == "table" then + local source = assert(code.source or code[1]) + local init = (code.lua_init == nil) and LUA_INIT or code.lua_init + return new_thread(code.prelude, init, source, ...) + end + + return new_thread(nil, LUA_INIT, code, ...) +end + +end +------------------------------------------------------------------------------- + +return threads \ No newline at end of file -- cgit v1.2.3-55-g6feb