diff options
author | moteus <mimir@newmail.ru> | 2013-12-26 14:34:13 +0400 |
---|---|---|
committer | moteus <mimir@newmail.ru> | 2013-12-26 14:45:02 +0400 |
commit | 92ec624951de2d344b28eb5262a3534822f6d6a7 (patch) | |
tree | 793f5c5ab09f05e0462489678b5186bb588d0b4a | |
parent | 7b90a331bf1caecfa1ba1e2f3e7f87fa01c389b9 (diff) | |
download | lua-llthreads2-92ec624951de2d344b28eb5262a3534822f6d6a7.tar.gz lua-llthreads2-92ec624951de2d344b28eb5262a3534822f6d6a7.tar.bz2 lua-llthreads2-92ec624951de2d344b28eb5262a3534822f6d6a7.zip |
Add. timeout parameter to thread:join() method
-rw-r--r-- | .travis.yml | 2 | ||||
-rw-r--r-- | README.md | 3 | ||||
-rw-r--r-- | src/llthread.c | 33 | ||||
-rw-r--r-- | test/test_join_timeout.lua | 64 | ||||
-rw-r--r-- | test/test_register_llthreads.lua | 12 |
5 files changed, 107 insertions, 7 deletions
diff --git a/.travis.yml b/.travis.yml index 7bb11c6..4a28f5e 100644 --- a/.travis.yml +++ b/.travis.yml | |||
@@ -47,6 +47,8 @@ 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 | ||
51 | - lua$LUA_SFX test_join_timeout.lua | ||
50 | 52 | ||
51 | notifications: | 53 | notifications: |
52 | email: | 54 | email: |
@@ -12,6 +12,9 @@ This is full dropin replacement for [llthreads](https://github.com/Neopallium/lu | |||
12 | * does not open all standart libraries (set LLTHREAD_REGISTER_STD_LIBRARY to on this feature) | 12 | * does not open all standart libraries (set LLTHREAD_REGISTER_STD_LIBRARY to on this feature) |
13 | * register loaders for llthreads library itself | 13 | * register loaders for llthreads library itself |
14 | 14 | ||
15 | ##Additional | ||
16 | * thread:join() method support zero timeout to check if thread alive | ||
17 | * thread:join() method support arbitrary timeout on Windows platform | ||
15 | 18 | ||
16 | [](https://bitdeli.com/free "Bitdeli Badge") | 19 | [](https://bitdeli.com/free "Bitdeli Badge") |
17 | 20 | ||
diff --git a/src/llthread.c b/src/llthread.c index 0449ea9..0f43e14 100644 --- a/src/llthread.c +++ b/src/llthread.c | |||
@@ -43,12 +43,16 @@ | |||
43 | # define OS_THREAD_RETURT unsigned int __stdcall | 43 | # define OS_THREAD_RETURT unsigned int __stdcall |
44 | # define INVALID_THREAD INVALID_HANDLE_VALUE | 44 | # define INVALID_THREAD INVALID_HANDLE_VALUE |
45 | # define INFINITE_JOIN_TIMEOUT INFINITE | 45 | # define INFINITE_JOIN_TIMEOUT INFINITE |
46 | # define JOIN_OK 0 | ||
47 | # define JOIN_ETIMEDOUT 1 | ||
46 | typedef DWORD join_timeout_t; | 48 | typedef DWORD join_timeout_t; |
47 | typedef HANDLE os_thread_t; | 49 | typedef HANDLE os_thread_t; |
48 | #else | 50 | #else |
49 | # define OS_THREAD_RETURT void * | 51 | # define OS_THREAD_RETURT void * |
50 | # define INVALID_THREAD 0 | 52 | # define INVALID_THREAD 0 |
51 | # define INFINITE_JOIN_TIMEOUT -1 | 53 | # define INFINITE_JOIN_TIMEOUT -1 |
54 | # define JOIN_OK 0 | ||
55 | # define JOIN_ETIMEDOUT ETIMEDOUT | ||
52 | typedef int join_timeout_t; | 56 | typedef int join_timeout_t; |
53 | typedef pthread_t os_thread_t; | 57 | typedef pthread_t os_thread_t; |
54 | #endif | 58 | #endif |
@@ -321,13 +325,15 @@ static void open_thread_libs(lua_State *L){ | |||
321 | /* get package.preload */ | 325 | /* get package.preload */ |
322 | lua_getglobal(L, "package"); lua_getfield(L, -1, "preload"); lua_remove(L, -2); | 326 | lua_getglobal(L, "package"); lua_getfield(L, -1, "preload"); lua_remove(L, -2); |
323 | 327 | ||
328 | /*always only register*/ | ||
329 | lua_pushcfunction(L, luaopen_llthreads); lua_setfield(L, -2, "llthreads"); | ||
330 | |||
324 | L_REGLIB(L, io, 1); | 331 | L_REGLIB(L, io, 1); |
325 | L_REGLIB(L, os, 1); | 332 | L_REGLIB(L, os, 1); |
326 | L_REGLIB(L, math, 1); | 333 | L_REGLIB(L, math, 1); |
327 | L_REGLIB(L, table, 1); | 334 | L_REGLIB(L, table, 1); |
328 | L_REGLIB(L, debug, 1); | 335 | L_REGLIB(L, debug, 1); |
329 | L_REGLIB(L, string, 1); | 336 | L_REGLIB(L, string, 1); |
330 | L_REGLIB(L, llthreads, 0); | ||
331 | 337 | ||
332 | lua_settop(L, top); | 338 | lua_settop(L, top); |
333 | #undef L_REGLIB | 339 | #undef L_REGLIB |
@@ -482,9 +488,24 @@ static int llthread_join(llthread_t *this, join_timeout_t timeout) { | |||
482 | } | 488 | } |
483 | return 2; | 489 | return 2; |
484 | #else | 490 | #else |
491 | int rc; | ||
492 | if(timeout == 0){ | ||
493 | rc = pthread_kill(this->thread, 0); | ||
494 | if(rc == 0){ /* still alive */ | ||
495 | rc = ETIMEDOUT; | ||
496 | } | ||
497 | if(rc == ESRCH){ /*thread dead*/ | ||
498 | FLAG_SET(this, TSTATE_JOINED); | ||
499 | rc = 0; | ||
500 | } | ||
501 | return rc; | ||
502 | } | ||
503 | |||
504 | // @todo use pthread_tryjoin_np to support timeout | ||
505 | |||
485 | /* then join the thread. */ | 506 | /* then join the thread. */ |
486 | int rc = pthread_join(this->thread, NULL); | 507 | rc = pthread_join(this->thread, NULL); |
487 | if(rc == 0) { | 508 | if((rc == 0) || (rc == ESRCH)) { |
488 | FLAG_SET(this, TSTATE_JOINED); | 509 | FLAG_SET(this, TSTATE_JOINED); |
489 | } | 510 | } |
490 | return rc; | 511 | return rc; |
@@ -598,7 +619,7 @@ static int l_llthread_join(lua_State *L) { | |||
598 | } | 619 | } |
599 | 620 | ||
600 | /* join the thread. */ | 621 | /* join the thread. */ |
601 | rc = llthread_join(this, INFINITE_JOIN_TIMEOUT); | 622 | rc = llthread_join(this, luaL_optint(L, 2, INFINITE_JOIN_TIMEOUT)); |
602 | 623 | ||
603 | /* Push all results after the Lua code. */ | 624 | /* Push all results after the Lua code. */ |
604 | if(child && FLAG_IS_SET(this, TSTATE_JOINED)) { | 625 | if(child && FLAG_IS_SET(this, TSTATE_JOINED)) { |
@@ -618,13 +639,11 @@ static int l_llthread_join(lua_State *L) { | |||
618 | return top; | 639 | return top; |
619 | } | 640 | } |
620 | 641 | ||
621 | #ifndef USE_PTHREAD | 642 | if( rc == JOIN_ETIMEDOUT ){ |
622 | if( rc == 1 ){ | ||
623 | lua_pushboolean(L, 0); | 643 | lua_pushboolean(L, 0); |
624 | lua_pushstring(L, "timeout"); | 644 | lua_pushstring(L, "timeout"); |
625 | return 2; | 645 | return 2; |
626 | } | 646 | } |
627 | #endif | ||
628 | 647 | ||
629 | { | 648 | { |
630 | char buf[ERROR_LEN]; | 649 | char buf[ERROR_LEN]; |
diff --git a/test/test_join_timeout.lua b/test/test_join_timeout.lua new file mode 100644 index 0000000..5beac2b --- /dev/null +++ b/test/test_join_timeout.lua | |||
@@ -0,0 +1,64 @@ | |||
1 | local llthreads = require"llthreads" | ||
2 | |||
3 | local sleep | ||
4 | local status, socket = pcall(require,"socket") | ||
5 | if status then | ||
6 | sleep = function(secs) | ||
7 | return socket.sleep(secs) | ||
8 | end | ||
9 | end | ||
10 | |||
11 | if not sleep then | ||
12 | local status, ztimer = pcall(require, "lzmq.timer") | ||
13 | if status then | ||
14 | sleep = function(secs) | ||
15 | ztimer.sleep(secs * 1000) | ||
16 | end | ||
17 | end | ||
18 | end | ||
19 | |||
20 | if not sleep then | ||
21 | sleep = function(secs) | ||
22 | os.execute("sleep " .. tonumber(secs)) | ||
23 | end | ||
24 | end | ||
25 | |||
26 | local include = [[ | ||
27 | local llthreads = require"llthreads" | ||
28 | |||
29 | local sleep | ||
30 | local status, socket = pcall(require,"socket") | ||
31 | if status then | ||
32 | sleep = function(secs) | ||
33 | return socket.sleep(secs) | ||
34 | end | ||
35 | end | ||
36 | |||
37 | if not sleep then | ||
38 | local status, ztimer = pcall(require, "lzmq.timer") | ||
39 | if status then | ||
40 | sleep = function(secs) | ||
41 | ztimer.sleep(secs * 1000) | ||
42 | end | ||
43 | end | ||
44 | end | ||
45 | |||
46 | if not sleep then | ||
47 | sleep = function(secs) | ||
48 | os.execute("sleep " .. tonumber(secs)) | ||
49 | end | ||
50 | end | ||
51 | ]] | ||
52 | |||
53 | local thread = llthreads.new(include .. [[ | ||
54 | sleep(5) | ||
55 | ]]) | ||
56 | thread:start() | ||
57 | local ok, err = thread:join(0) | ||
58 | print("thread:join(0): ", ok, err) | ||
59 | assert(ok == false) | ||
60 | assert(err == "timeout") | ||
61 | |||
62 | print("thread:join(): ", thread:join()) | ||
63 | print("Done!") | ||
64 | |||
diff --git a/test/test_register_llthreads.lua b/test/test_register_llthreads.lua new file mode 100644 index 0000000..f02bf86 --- /dev/null +++ b/test/test_register_llthreads.lua | |||
@@ -0,0 +1,12 @@ | |||
1 | local llthreads = require "llthreads" | ||
2 | local thread = llthreads.new([[ | ||
3 | if not package.preload.llthreads then | ||
4 | print("llthreads does not register in thread") | ||
5 | os.exit(-1) | ||
6 | end | ||
7 | local ok, err = pcall(require, "llthreads") | ||
8 | if not ok then | ||
9 | print("can not load llthreads: ", err) | ||
10 | os.exit(-2) | ||
11 | end | ||
12 | ]]):start():join() | ||