diff options
Diffstat (limited to 'src/lua')
| -rw-r--r-- | src/lua/llthreads2/ex.lua | 152 |
1 files changed, 152 insertions, 0 deletions
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 @@ | |||
| 1 | -- | ||
| 2 | -- wraps the low-level threads object. | ||
| 3 | -- | ||
| 4 | |||
| 5 | -- | ||
| 6 | -- Note! Define this function prior all `local` definitions | ||
| 7 | -- to prevent use upvalue by accident | ||
| 8 | -- | ||
| 9 | local bootstrap_code = require"string".dump(function(lua_init, prelude, code, ...) | ||
| 10 | local loadstring = loadstring or load | ||
| 11 | local unpack = table.unpack or unpack | ||
| 12 | |||
| 13 | local function load_src(str) | ||
| 14 | local f, n | ||
| 15 | if str:sub(1,1) == '@' then | ||
| 16 | n = str:sub(2) | ||
| 17 | f = assert(loadfile(n)) | ||
| 18 | else | ||
| 19 | n = '=(loadstring)' | ||
| 20 | f = assert(loadstring(str)) | ||
| 21 | end | ||
| 22 | return f, n | ||
| 23 | end | ||
| 24 | |||
| 25 | local function pack_n(...) | ||
| 26 | return { n = select("#", ...), ... } | ||
| 27 | end | ||
| 28 | |||
| 29 | local function unpack_n(t) | ||
| 30 | return unpack(t, 1, t.n) | ||
| 31 | end | ||
| 32 | |||
| 33 | if lua_init and #lua_init > 0 then | ||
| 34 | local init = load_src(lua_init) | ||
| 35 | init() | ||
| 36 | end | ||
| 37 | |||
| 38 | local args | ||
| 39 | |||
| 40 | if prelude and #prelude > 0 then | ||
| 41 | prelude = load_src(prelude) | ||
| 42 | args = pack_n(prelude(...)) | ||
| 43 | else | ||
| 44 | args = pack_n(...) | ||
| 45 | end | ||
| 46 | |||
| 47 | local func | ||
| 48 | func, args[0] = load_src(code) | ||
| 49 | |||
| 50 | _G.arg = args | ||
| 51 | arg = args | ||
| 52 | |||
| 53 | return func(unpack_n(args)) | ||
| 54 | end) | ||
| 55 | |||
| 56 | local ok, llthreads = pcall(require, "llthreads2") | ||
| 57 | if not ok then llthreads = require"llthreads" end | ||
| 58 | |||
| 59 | local os = require"os" | ||
| 60 | local string = require"string" | ||
| 61 | local table = require"table" | ||
| 62 | |||
| 63 | local setmetatable, tonumber, assert = setmetatable, tonumber, assert | ||
| 64 | |||
| 65 | ------------------------------------------------------------------------------- | ||
| 66 | local LUA_INIT = "LUA_INIT" do | ||
| 67 | |||
| 68 | local lua_version_t | ||
| 69 | local function lua_version() | ||
| 70 | if not lua_version_t then | ||
| 71 | local version = assert(_G._VERSION) | ||
| 72 | local maj,min = version:match("^Lua (%d+)%.(%d+)$") | ||
| 73 | if maj then lua_version_t = {tonumber(maj),tonumber(min)} | ||
| 74 | elseif not math.mod then lua_version_t = {5,2} | ||
| 75 | elseif table.pack and not pack then lua_version_t = {5,2} | ||
| 76 | else lua_version_t = {5,2} end | ||
| 77 | end | ||
| 78 | return lua_version_t[1], lua_version_t[2] | ||
| 79 | end | ||
| 80 | |||
| 81 | local LUA_MAJOR, LUA_MINOR = lua_version() | ||
| 82 | local IS_LUA_51 = (LUA_MAJOR == 5) and (LUA_MINOR == 1) | ||
| 83 | |||
| 84 | local LUA_INIT_VER | ||
| 85 | if not IS_LUA_51 then | ||
| 86 | LUA_INIT_VER = LUA_INIT .. "_" .. LUA_MAJOR .. "_" .. LUA_MINOR | ||
| 87 | end | ||
| 88 | |||
| 89 | LUA_INIT = LUA_INIT_VER and os.getenv( LUA_INIT_VER ) or os.getenv( LUA_INIT ) or "" | ||
| 90 | |||
| 91 | end | ||
| 92 | ------------------------------------------------------------------------------- | ||
| 93 | |||
| 94 | ------------------------------------------------------------------------------- | ||
| 95 | local thread_mt = {} do | ||
| 96 | thread_mt.__index = thread_mt | ||
| 97 | |||
| 98 | function thread_mt:start(...) | ||
| 99 | local ok, err = self.thread:start(...) | ||
| 100 | if not ok then return nil, err end | ||
| 101 | return self | ||
| 102 | end | ||
| 103 | |||
| 104 | function thread_mt:join(...) | ||
| 105 | return self.thread:join(...) | ||
| 106 | end | ||
| 107 | |||
| 108 | function thread_mt:alive() | ||
| 109 | return self.thread:alive() | ||
| 110 | end | ||
| 111 | |||
| 112 | end | ||
| 113 | ------------------------------------------------------------------------------- | ||
| 114 | |||
| 115 | ------------------------------------------------------------------------------- | ||
| 116 | local threads = {} do | ||
| 117 | |||
| 118 | local function new_thread(prelude, lua_init, code, ...) | ||
| 119 | if type(lua_init) == "function" then | ||
| 120 | lua_init = string.dump(lua_init) | ||
| 121 | end | ||
| 122 | |||
| 123 | if type(prelude) == "function" then | ||
| 124 | prelude = string.dump(prelude) | ||
| 125 | end | ||
| 126 | |||
| 127 | if type(code) == "function" then | ||
| 128 | code = string.dump(code) | ||
| 129 | end | ||
| 130 | |||
| 131 | local thread = llthreads.new(bootstrap_code, lua_init, prelude, code, ...) | ||
| 132 | return setmetatable({ | ||
| 133 | thread = thread, | ||
| 134 | }, thread_mt) | ||
| 135 | end | ||
| 136 | |||
| 137 | threads.new = function (code, ...) | ||
| 138 | assert(code) | ||
| 139 | |||
| 140 | if type(code) == "table" then | ||
| 141 | local source = assert(code.source or code[1]) | ||
| 142 | local init = (code.lua_init == nil) and LUA_INIT or code.lua_init | ||
| 143 | return new_thread(code.prelude, init, source, ...) | ||
| 144 | end | ||
| 145 | |||
| 146 | return new_thread(nil, LUA_INIT, code, ...) | ||
| 147 | end | ||
| 148 | |||
| 149 | end | ||
| 150 | ------------------------------------------------------------------------------- | ||
| 151 | |||
| 152 | return threads \ No newline at end of file | ||
