Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
`llthreads` library rewritten without `LuaNativeObjects` code generator
Lua CMake C Shell
branch: master
Failed to load latest commit information.
.travis
cmake Add. LuaDist files.
msvc Fix. load library on Lua 5.2
rockspecs Prepare release and bump version numbers to 0.1.3
src Fix. Version on Lua 5.3
test Add. Test for multiple prelude.
.gitignore Update gitignore. [ci skip]
.travis.yml Add. Test for multiple prelude.
CMakeLists.txt Fix. CMakeLists file install `llthreads2.ex` module.
COPYRIGHT.llthreads First commit.
LICENSE Fix. Version on Lua 5.3
README.md Update README.md
dist.info Prepare release and bump version numbers to 0.1.3
lakeconfig.lua Add. lakefile
lakefile

README.md

lua-llthreads2

Build Status Build Status Build Status

This is full dropin replacement for llthreads library.

Incompatibility list with origin llthreads library

  • does not support Lua 5.0
  • does not support ffi interface (use Lua C API for LuaJIT)
  • returns nil instead of false on error
  • start method returns self instead of true on success

Additional

  • thread:join() method support zero timeout to check if thread alive (does not work on Windows with pthreads)
  • thread:join() method support arbitrary timeout on Windows threads
  • thread:alive() method return whether the thread is alive (does not work on Windows with pthreads)
  • set_logger function allow logging errors (crash Lua VM) in current llthread's threads
  • thread:start() has additional parameter which control in which thread child Lua VM will be destroyed
  • allow pass cfunctions to child thread (e.g. to initialize Lua state)

Thread start arguments

detached joinable join returns child state closes by gc calls detach on
false false true child join <NEVER>
false(*) true(*) Lua values parent join <NEVER>
true false(*) raise error child <NONE> start
true true true child detach gc

Usage

Use custom logger

In this example I use lua-log library.

-- This is child thread.
local llthreads = require "llthreads2"
-- Send logs using ZMQ
local LOG = require"log".new(
  require "log.writer.net.zmq".new("tcp://127.0.0.1:5555")
)
llthread.set_logger(function(msg) LOG.error(msg) end)
-- This error with traceback will be passed to logger
error("SOME ERROR")

Start attached thread collectd in child thread

-- This is main thread.
local thread = require "llthreads2".new[[
  require "utils".sleep(5)
]]

-- We tell that we start attached thread but child Lua State shuld be close in child thread. 
-- If `thread` became garbage in main thread then finallizer calls thread:join() 
-- and main thread may hungup. But because of child state closes in child thread all objects
-- in this state can be destroyed and we can prevent deadlock.
thread:start(false, false)

-- We can call join.
-- Because of Lua state destroys in child thread we can not get 
-- returned Lua vaules so we just returns `true`.
thread:join()

Start detached joinable thread

-- This is main thread.
local thread = require "llthreads2".new[[
  require "utils".sleep(5)
]]

-- We tell that we start detached joinable thread. In fact we start attached 
-- thread but if `thread` became garbage in main thread then finallizer just 
-- detach child thread and main thread may not hungup.
thread:start(true, true)

-- We can call join.
-- Because of Lua state destroys in child thread we can not get 
-- returned Lua vaules so we just returns `true`.
thread:join()

Pass to child thread host application`s library loader

If you close parent Lua state then some dynamic library may be unloaded and cfunction in child Lua state (thread) became invalid.

-- `myhost.XXX` modules is built-in modules in host application
-- host application registers cfunction as module loader
local preload = {}
preload[ 'myhost.logger' ] = package.preload[ 'myhost.logger' ]
preload[ 'myhost.config' ] = package.preload[ 'myhost.config' ]
llthreads.new([[
  -- registers preload
  local preload  = ...
  for name, fn in pairs(preload) do package.preload[name] = fn end

  local log = require 'myhost.logger'

]], preload):start(true)

Wait while thread is alive

local thread = require "llthreads2".new[[
  require "utils".sleep(5)
  return 1
]]
thread:start()

-- we can not use `thread:join(0)` because we can not call it twice
-- so all returned vaules will be lost
while thread:alive() do 
  -- do some work
end

local ok, ret = thread:join() -- true, 1

Use ex module

local Threads = require "llthreads2.ex"

local ok, v = Threads.new(function()
  return 1
end):start():join()
assert(v == 1)

local thread = Threads.new({
  -- this thread code gets changed arguments
  function(a, b)
    assert(1 == a)
    assert(2 == b)
    print("Done")
  end;

  -- prelude can change thread arguments
  prelude = function(a, b)
    assert("1" == a)
    assert(nil == b)
    return tonumber(a), 2
  end;
}, "1")

thread:start():join()

Bitdeli Badge

Something went wrong with that request. Please try again.