diff options
Diffstat (limited to 'src')
-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 | ||