aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormoteus <mimir@newmail.ru>2013-12-26 14:34:13 +0400
committermoteus <mimir@newmail.ru>2013-12-26 14:45:02 +0400
commit92ec624951de2d344b28eb5262a3534822f6d6a7 (patch)
tree793f5c5ab09f05e0462489678b5186bb588d0b4a
parent7b90a331bf1caecfa1ba1e2f3e7f87fa01c389b9 (diff)
downloadlua-llthreads2-92ec624951de2d344b28eb5262a3534822f6d6a7.tar.gz
lua-llthreads2-92ec624951de2d344b28eb5262a3534822f6d6a7.tar.bz2
lua-llthreads2-92ec624951de2d344b28eb5262a3534822f6d6a7.zip
Add. timeout parameter to thread:join() method
-rw-r--r--.travis.yml2
-rw-r--r--README.md3
-rw-r--r--src/llthread.c33
-rw-r--r--test/test_join_timeout.lua64
-rw-r--r--test/test_register_llthreads.lua12
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
51notifications: 53notifications:
52 email: 54 email:
diff --git a/README.md b/README.md
index 2ca6f36..c0b67bf 100644
--- a/README.md
+++ b/README.md
@@ -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[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/moteus/lua-llthreads2/trend.png)](https://bitdeli.com/free "Bitdeli Badge") 19[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/moteus/lua-llthreads2/trend.png)](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
46typedef DWORD join_timeout_t; 48typedef DWORD join_timeout_t;
47typedef HANDLE os_thread_t; 49typedef 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
52typedef int join_timeout_t; 56typedef int join_timeout_t;
53typedef pthread_t os_thread_t; 57typedef 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 @@
1local llthreads = require"llthreads"
2
3local sleep
4local status, socket = pcall(require,"socket")
5if status then
6 sleep = function(secs)
7 return socket.sleep(secs)
8 end
9end
10
11if 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
18end
19
20if not sleep then
21 sleep = function(secs)
22 os.execute("sleep " .. tonumber(secs))
23 end
24end
25
26local include = [[
27local llthreads = require"llthreads"
28
29local sleep
30local status, socket = pcall(require,"socket")
31if status then
32 sleep = function(secs)
33 return socket.sleep(secs)
34 end
35end
36
37if 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
44end
45
46if not sleep then
47 sleep = function(secs)
48 os.execute("sleep " .. tonumber(secs))
49 end
50end
51]]
52
53local thread = llthreads.new(include .. [[
54 sleep(5)
55]])
56thread:start()
57local ok, err = thread:join(0)
58print("thread:join(0): ", ok, err)
59assert(ok == false)
60assert(err == "timeout")
61
62print("thread:join(): ", thread:join())
63print("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 @@
1local llthreads = require "llthreads"
2local 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()