From 18464f368d90b0f8ce48cb5d45def6f9d87e3432 Mon Sep 17 00:00:00 2001 From: moteus Date: Mon, 30 Dec 2013 12:58:48 +0400 Subject: Change. does not register llthread loader. This is because of better load dynamic library from child thread to prevent unload dynamic library if parent Lua state closes. --- .travis.yml | 2 +- README.md | 21 ++++++++++++++++++++- src/llthread.c | 22 +++++++++++++--------- test/test_join_timeout.lua | 7 ++++--- test/test_logger.lua | 4 +++- test/test_register_llthreads.lua | 3 +++ 6 files changed, 44 insertions(+), 15 deletions(-) diff --git a/.travis.yml b/.travis.yml index d02d26a..e5d2f0f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -47,7 +47,7 @@ script: - lua$LUA_SFX test_table_copy.lua - lua$LUA_SFX test_threads.lua - lua$LUA_SFX test_llthreads.lua - - lua$LUA_SFX test_register_llthreads.lua + # - lua$LUA_SFX test_register_llthreads.lua - lua$LUA_SFX test_join_timeout.lua - lua$LUA_SFX test_join_detach.lua - lua$LUA_SFX test_register_ffi.lua diff --git a/README.md b/README.md index b18459e..d23fc7c 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,6 @@ This is full dropin replacement for [llthreads](https://github.com/Neopallium/lu * 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 -* register loaders for llthreads library itself ##Additional * thread:join() method support zero timeout to check if thread alive (does not work on Windows with pthreads) @@ -68,5 +67,25 @@ thread:start(true, 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. + +``` Lua +-- `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) +``` + [![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/moteus/lua-llthreads2/trend.png)](https://bitdeli.com/free "Bitdeli Badge") diff --git a/src/llthread.c b/src/llthread.c index 88498a8..f7a9b59 100644 --- a/src/llthread.c +++ b/src/llthread.c @@ -340,17 +340,16 @@ void llthread_log(lua_State *L, const char *hdr, const char *msg){ //{ llthread_child static void open_thread_libs(lua_State *L){ +#define L_REGLIB(L, name) lua_pushcfunction(L, luaopen_##name); lua_setfield(L, -2) + int top = lua_gettop(L); #ifndef LLTHREAD_REGISTER_STD_LIBRARY + luaL_openlibs(L); lua_getglobal(L, "package"); lua_getfield(L, -1, "preload"); lua_remove(L, -2); - lua_pushcfunction(L, luaopen_llthreads); lua_setfield(L, -2, "llthreads"); - lua_settop(L, top); - return; -#else -#define L_REGLIB(L, name, G) lua_pushcfunction(L, luaopen_##name); lua_setfield(L, -2, #name) +#else lutil_require(L, "_G", luaopen_base, 1); lutil_require(L, "package", luaopen_package, 1); @@ -363,13 +362,12 @@ static void open_thread_libs(lua_State *L){ L_REGLIB(L, math, 1); L_REGLIB(L, table, 1); L_REGLIB(L, string, 1); - L_REGLIB(L, llthreads, 0); #ifdef LUA_DBLIBNAME L_REGLIB(L, debug, 1); #endif - /* @fixme find out luaopen_XXX in runtime */ + /* @fixme find out luaopen_XXX at runtime */ #ifdef LUA_JITLIBNAME L_REGLIB(L, bit, 1); L_REGLIB(L, jit, 1); @@ -378,10 +376,15 @@ static void open_thread_libs(lua_State *L){ L_REGLIB(L, bit32, 1); #endif - lua_settop(L, top); -#undef L_REGLIB +#endif +#ifdef LLTHREAD_REGISTER_THREAD_LIBRARY + L_REGLIB(L, llthreads, 0); #endif + + lua_settop(L, top); + +#undef L_REGLIB } static llthread_child_t *llthread_child_new() { @@ -529,6 +532,7 @@ static int llthread_detach(llthread_t *this){ int rc = 0; assert(FLAGS_IS_SET(this, TSTATE_STARTED)); + assert(this->child != NULL); /*we can not deatach joined thread*/ if(FLAGS_IS_SET(this, TSTATE_JOINED)) diff --git a/test/test_join_timeout.lua b/test/test_join_timeout.lua index aa8f88d..b9cf155 100644 --- a/test/test_join_timeout.lua +++ b/test/test_join_timeout.lua @@ -2,9 +2,8 @@ local llthreads = require"llthreads" local utils = require "utils" local sleep = utils.sleep -local include = [[ +local include = utils.thread_init .. [[ local llthreads = require"llthreads" -]] .. utils.thread_init .. [[ local sleep = require "utils".sleep ]] @@ -17,6 +16,8 @@ print("thread:join(0): ", ok, err) assert(ok == nil) assert(err == "timeout") -print("thread:join(): ", thread:join()) +local ok, err = thread:join() +print("thread:join(): ", ok, err) +assert(ok, err) print("Done!") diff --git a/test/test_logger.lua b/test/test_logger.lua index 66c190f..f85a896 100644 --- a/test/test_logger.lua +++ b/test/test_logger.lua @@ -1,4 +1,6 @@ -require "llthreads".new([[ +local utils = require "utils" + +require "llthreads".new(utils.thread_init .. [[ require "string" require "llthreads".set_logger(function(msg) diff --git a/test/test_register_llthreads.lua b/test/test_register_llthreads.lua index f02bf86..5b234a9 100644 --- a/test/test_register_llthreads.lua +++ b/test/test_register_llthreads.lua @@ -1,3 +1,6 @@ +-- Test if you build module with +-- LLTHREAD_REGISTER_THREAD_LIBRARY + local llthreads = require "llthreads" local thread = llthreads.new([[ if not package.preload.llthreads then -- cgit v1.2.3-55-g6feb