diff options
| author | moteus <mimir@newmail.ru> | 2013-12-30 12:58:48 +0400 |
|---|---|---|
| committer | moteus <mimir@newmail.ru> | 2013-12-30 12:58:48 +0400 |
| commit | 18464f368d90b0f8ce48cb5d45def6f9d87e3432 (patch) | |
| tree | 89d9c45aa5a25fe361b6ec4bd5495375664b0b81 | |
| parent | a087c2737441aad781be7e3d88775e688152ad4e (diff) | |
| download | lua-llthreads2-18464f368d90b0f8ce48cb5d45def6f9d87e3432.tar.gz lua-llthreads2-18464f368d90b0f8ce48cb5d45def6f9d87e3432.tar.bz2 lua-llthreads2-18464f368d90b0f8ce48cb5d45def6f9d87e3432.zip | |
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.
| -rw-r--r-- | .travis.yml | 2 | ||||
| -rw-r--r-- | README.md | 21 | ||||
| -rw-r--r-- | src/llthread.c | 22 | ||||
| -rw-r--r-- | test/test_join_timeout.lua | 7 | ||||
| -rw-r--r-- | test/test_logger.lua | 4 | ||||
| -rw-r--r-- | 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: | |||
| 47 | - lua$LUA_SFX test_table_copy.lua | 47 | - lua$LUA_SFX test_table_copy.lua |
| 48 | - lua$LUA_SFX test_threads.lua | 48 | - lua$LUA_SFX test_threads.lua |
| 49 | - lua$LUA_SFX test_llthreads.lua | 49 | - lua$LUA_SFX test_llthreads.lua |
| 50 | - lua$LUA_SFX test_register_llthreads.lua | 50 | # - lua$LUA_SFX test_register_llthreads.lua |
| 51 | - lua$LUA_SFX test_join_timeout.lua | 51 | - lua$LUA_SFX test_join_timeout.lua |
| 52 | - lua$LUA_SFX test_join_detach.lua | 52 | - lua$LUA_SFX test_join_detach.lua |
| 53 | - lua$LUA_SFX test_register_ffi.lua | 53 | - lua$LUA_SFX test_register_ffi.lua |
| @@ -9,7 +9,6 @@ This is full dropin replacement for [llthreads](https://github.com/Neopallium/lu | |||
| 9 | * does not support ffi interface (use Lua C API for LuaJIT) | 9 | * does not support ffi interface (use Lua C API for LuaJIT) |
| 10 | * returns nil instead of false on error | 10 | * returns nil instead of false on error |
| 11 | * start method returns self instead of true on success | 11 | * start method returns self instead of true on success |
| 12 | * register loaders for llthreads library itself | ||
| 13 | 12 | ||
| 14 | ##Additional | 13 | ##Additional |
| 15 | * thread:join() method support zero timeout to check if thread alive (does not work on Windows with pthreads) | 14 | * 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) | |||
| 68 | thread:join() | 67 | thread:join() |
| 69 | ``` | 68 | ``` |
| 70 | 69 | ||
| 70 | ### Pass to child thread host application`s library loader | ||
| 71 | If you close parent Lua state then some dynamic library may be unloaded | ||
| 72 | and cfunction in child Lua state (thread) became invalid. | ||
| 73 | |||
| 74 | ``` Lua | ||
| 75 | -- `myhost.XXX` modules is built-in modules in host application | ||
| 76 | -- host application registers cfunction as module loader | ||
| 77 | local preload = {} | ||
| 78 | preload[ 'myhost.logger' ] = package.preload[ 'myhost.logger' ] | ||
| 79 | preload[ 'myhost.config' ] = package.preload[ 'myhost.config' ] | ||
| 80 | llthreads.new([[ | ||
| 81 | -- registers preload | ||
| 82 | local preload = ... | ||
| 83 | for name, fn in pairs(preload) do package.preload[name] = fn end | ||
| 84 | |||
| 85 | local log = require 'myhost.logger' | ||
| 86 | |||
| 87 | ]], preload):start(true) | ||
| 88 | ``` | ||
| 89 | |||
| 71 | [](https://bitdeli.com/free "Bitdeli Badge") | 90 | [](https://bitdeli.com/free "Bitdeli Badge") |
| 72 | 91 | ||
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){ | |||
| 340 | //{ llthread_child | 340 | //{ llthread_child |
| 341 | 341 | ||
| 342 | static void open_thread_libs(lua_State *L){ | 342 | static void open_thread_libs(lua_State *L){ |
| 343 | #define L_REGLIB(L, name) lua_pushcfunction(L, luaopen_##name); lua_setfield(L, -2) | ||
| 344 | |||
| 343 | int top = lua_gettop(L); | 345 | int top = lua_gettop(L); |
| 344 | 346 | ||
| 345 | #ifndef LLTHREAD_REGISTER_STD_LIBRARY | 347 | #ifndef LLTHREAD_REGISTER_STD_LIBRARY |
| 348 | |||
| 346 | luaL_openlibs(L); | 349 | luaL_openlibs(L); |
| 347 | lua_getglobal(L, "package"); lua_getfield(L, -1, "preload"); lua_remove(L, -2); | 350 | lua_getglobal(L, "package"); lua_getfield(L, -1, "preload"); lua_remove(L, -2); |
| 348 | lua_pushcfunction(L, luaopen_llthreads); lua_setfield(L, -2, "llthreads"); | ||
| 349 | lua_settop(L, top); | ||
| 350 | return; | ||
| 351 | #else | ||
| 352 | 351 | ||
| 353 | #define L_REGLIB(L, name, G) lua_pushcfunction(L, luaopen_##name); lua_setfield(L, -2, #name) | 352 | #else |
| 354 | 353 | ||
| 355 | lutil_require(L, "_G", luaopen_base, 1); | 354 | lutil_require(L, "_G", luaopen_base, 1); |
| 356 | lutil_require(L, "package", luaopen_package, 1); | 355 | lutil_require(L, "package", luaopen_package, 1); |
| @@ -363,13 +362,12 @@ static void open_thread_libs(lua_State *L){ | |||
| 363 | L_REGLIB(L, math, 1); | 362 | L_REGLIB(L, math, 1); |
| 364 | L_REGLIB(L, table, 1); | 363 | L_REGLIB(L, table, 1); |
| 365 | L_REGLIB(L, string, 1); | 364 | L_REGLIB(L, string, 1); |
| 366 | L_REGLIB(L, llthreads, 0); | ||
| 367 | 365 | ||
| 368 | #ifdef LUA_DBLIBNAME | 366 | #ifdef LUA_DBLIBNAME |
| 369 | L_REGLIB(L, debug, 1); | 367 | L_REGLIB(L, debug, 1); |
| 370 | #endif | 368 | #endif |
| 371 | 369 | ||
| 372 | /* @fixme find out luaopen_XXX in runtime */ | 370 | /* @fixme find out luaopen_XXX at runtime */ |
| 373 | #ifdef LUA_JITLIBNAME | 371 | #ifdef LUA_JITLIBNAME |
| 374 | L_REGLIB(L, bit, 1); | 372 | L_REGLIB(L, bit, 1); |
| 375 | L_REGLIB(L, jit, 1); | 373 | L_REGLIB(L, jit, 1); |
| @@ -378,10 +376,15 @@ static void open_thread_libs(lua_State *L){ | |||
| 378 | L_REGLIB(L, bit32, 1); | 376 | L_REGLIB(L, bit32, 1); |
| 379 | #endif | 377 | #endif |
| 380 | 378 | ||
| 381 | lua_settop(L, top); | 379 | #endif |
| 382 | #undef L_REGLIB | ||
| 383 | 380 | ||
| 381 | #ifdef LLTHREAD_REGISTER_THREAD_LIBRARY | ||
| 382 | L_REGLIB(L, llthreads, 0); | ||
| 384 | #endif | 383 | #endif |
| 384 | |||
| 385 | lua_settop(L, top); | ||
| 386 | |||
| 387 | #undef L_REGLIB | ||
| 385 | } | 388 | } |
| 386 | 389 | ||
| 387 | static llthread_child_t *llthread_child_new() { | 390 | static llthread_child_t *llthread_child_new() { |
| @@ -529,6 +532,7 @@ static int llthread_detach(llthread_t *this){ | |||
| 529 | int rc = 0; | 532 | int rc = 0; |
| 530 | 533 | ||
| 531 | assert(FLAGS_IS_SET(this, TSTATE_STARTED)); | 534 | assert(FLAGS_IS_SET(this, TSTATE_STARTED)); |
| 535 | assert(this->child != NULL); | ||
| 532 | 536 | ||
| 533 | /*we can not deatach joined thread*/ | 537 | /*we can not deatach joined thread*/ |
| 534 | if(FLAGS_IS_SET(this, TSTATE_JOINED)) | 538 | 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" | |||
| 2 | local utils = require "utils" | 2 | local utils = require "utils" |
| 3 | local sleep = utils.sleep | 3 | local sleep = utils.sleep |
| 4 | 4 | ||
| 5 | local include = [[ | 5 | local include = utils.thread_init .. [[ |
| 6 | local llthreads = require"llthreads" | 6 | local llthreads = require"llthreads" |
| 7 | ]] .. utils.thread_init .. [[ | ||
| 8 | local sleep = require "utils".sleep | 7 | local sleep = require "utils".sleep |
| 9 | ]] | 8 | ]] |
| 10 | 9 | ||
| @@ -17,6 +16,8 @@ print("thread:join(0): ", ok, err) | |||
| 17 | assert(ok == nil) | 16 | assert(ok == nil) |
| 18 | assert(err == "timeout") | 17 | assert(err == "timeout") |
| 19 | 18 | ||
| 20 | print("thread:join(): ", thread:join()) | 19 | local ok, err = thread:join() |
| 20 | print("thread:join(): ", ok, err) | ||
| 21 | assert(ok, err) | ||
| 21 | print("Done!") | 22 | print("Done!") |
| 22 | 23 | ||
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 @@ | |||
| 1 | require "llthreads".new([[ | 1 | local utils = require "utils" |
| 2 | |||
| 3 | require "llthreads".new(utils.thread_init .. [[ | ||
| 2 | require "string" | 4 | require "string" |
| 3 | 5 | ||
| 4 | require "llthreads".set_logger(function(msg) | 6 | 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 @@ | |||
| 1 | -- Test if you build module with | ||
| 2 | -- LLTHREAD_REGISTER_THREAD_LIBRARY | ||
| 3 | |||
| 1 | local llthreads = require "llthreads" | 4 | local llthreads = require "llthreads" |
| 2 | local thread = llthreads.new([[ | 5 | local thread = llthreads.new([[ |
| 3 | if not package.preload.llthreads then | 6 | if not package.preload.llthreads then |
