Permalink
Cannot retrieve contributors at this time
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
lua-llthreads2/src/lua/llthreads2/ex.lua
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
207 lines (167 sloc)
5.28 KB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| --- Wraps the low-level threads object. | |
| -- | |
| -- @module llthreads2.ex | |
| -- | |
| -- 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 | |
| --- Thread object. | |
| -- | |
| -- @type thread | |
| --- Start thread. | |
| -- | |
| -- @tparam ?boolean detached | |
| -- @tparam ?boolean joinable | |
| -- @return self | |
| function thread_mt:start(...) | |
| local ok, err = self.thread:start(...) | |
| if not ok then return nil, err end | |
| return self | |
| end | |
| --- Join thread. | |
| -- | |
| -- @tparam ?number timeout Windows suppurts arbitrary value, but POSIX supports only 0 | |
| function thread_mt:join(...) | |
| return self.thread:join(...) | |
| end | |
| --- Check if thread still working. | |
| -- You can call `join` to get returned values if thiread is not alive. | |
| function thread_mt:alive() | |
| return self.thread:alive() | |
| end | |
| --- Check if thread was started. | |
| -- | |
| function thread_mt:started() | |
| return self.thread:started() | |
| end | |
| --- Check if thread is detached. | |
| -- This function returns valid value only for started thread. | |
| function thread_mt:detached() | |
| return self.thread:detached() | |
| end | |
| --- Check if thread is joinable. | |
| -- This function returns valid value only for started thread. | |
| function thread_mt:joinable() | |
| return self.thread:joinable() | |
| end | |
| --- Interrupt thread | |
| -- The thread is interrupted by installing a debug hook that | |
| -- creates an error. | |
| -- @tparam ?boolean if not given, interrupt only once, | |
| -- otherwise this arg sets or unsets permanent interrupt. | |
| function thread_mt:interrupt(arg) | |
| return self.thread:interrupt(arg) | |
| end | |
| end | |
| ------------------------------------------------------------------------------- | |
| ------------------------------------------------------------------------------- | |
| local threads = {} do | |
| local function new_thread(lua_init, prelude, 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 | |
| --- Create new thread object | |
| -- | |
| -- @tparam string|function|THREAD_OPTIONS source thread source code. | |
| -- | |
| 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(init, code.prelude, source, ...) | |
| end | |
| return new_thread(LUA_INIT, nil, code, ...) | |
| end | |
| end | |
| ------------------------------------------------------------------------------- | |
| --- A table describe threads constructor options. | |
| -- | |
| -- @tfield string|function source thread source code (or first value of table) | |
| -- @tfield ?string|function prelude thread prelude code. This code can change thread arguments. | |
| -- e.g. it can remove some values or change their type. | |
| -- @lua_init ?string|function|false by default child lua state try use LUA_INIT environment variable | |
| -- just like regular lua interpretator. | |
| -- | |
| -- @table THREAD_OPTIONS | |
| return threads |