aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlexey Melnichuk <mimir@newmail.ru>2014-02-04 11:06:17 +0400
committerAlexey Melnichuk <mimir@newmail.ru>2014-02-04 11:06:17 +0400
commitcef9a7a112a8322e2c6498021df59e4a8f7b5246 (patch)
tree5a885427afef52cbd3067c79b1f24406e42ecf87 /src
parentd35bf824e0dd9c3584d1587b5ec662a0fcf71bfe (diff)
downloadlua-llthreads2-cef9a7a112a8322e2c6498021df59e4a8f7b5246.tar.gz
lua-llthreads2-cef9a7a112a8322e2c6498021df59e4a8f7b5246.tar.bz2
lua-llthreads2-cef9a7a112a8322e2c6498021df59e4a8f7b5246.zip
Add. `thread:alive()` method.
Diffstat (limited to 'src')
-rw-r--r--src/llthread.c69
1 files changed, 69 insertions, 0 deletions
diff --git a/src/llthread.c b/src/llthread.c
index ac485e3..0ffa727 100644
--- a/src/llthread.c
+++ b/src/llthread.c
@@ -457,6 +457,35 @@ static int llthread_join(llthread_t *this, join_timeout_t timeout) {
457 } 457 }
458} 458}
459 459
460static int llthread_alive(llthread_t *this) {
461 llthread_validate(this);
462
463 if(IS(this, JOINED)){
464 return JOIN_OK;
465 } else{
466#ifndef USE_PTHREAD
467 DWORD ret = 0;
468 if(INVALID_THREAD == this->thread) return JOIN_OK;
469 ret = WaitForSingleObject( this->thread, 0 );
470 if( ret == WAIT_OBJECT_0) return JOIN_OK;
471 if( ret == WAIT_TIMEOUT ) return JOIN_ETIMEDOUT;
472 return JOIN_FAIL;
473#else
474 int rc = pthread_kill(this->thread, 0);
475 if(rc == 0){ /* still alive */
476 return JOIN_ETIMEDOUT;
477 }
478
479 if(rc != ESRCH){
480 /*@fixme what else it can be ?*/
481 return rc;
482 }
483
484 return JOIN_OK;
485#endif
486 }
487}
488
460static llthread_t *llthread_create(lua_State *L, const char *code, size_t code_len) { 489static llthread_t *llthread_create(lua_State *L, const char *code, size_t code_len) {
461 llthread_t *this = llthread_new(); 490 llthread_t *this = llthread_new();
462 llthread_child_t *child = this->child; 491 llthread_child_t *child = this->child;
@@ -592,6 +621,45 @@ static int l_llthread_join(lua_State *L) {
592 621
593} 622}
594 623
624static int l_llthread_alive(lua_State *L) {
625 llthread_t *this = l_llthread_at(L, 1);
626 llthread_child_t *child = this->child;
627 int rc;
628
629 if(!IS(this, STARTED )) {
630 return fail(L, "Can't join a thread that hasn't be started.");
631 }
632 if( IS(this, DETACHED) && !IS(this, JOINABLE)) {
633 return fail(L, "Can't join a thread that has been detached.");
634 }
635 if( IS(this, JOINED )) {
636 return fail(L, "Can't join a thread that has already been joined.");
637 }
638
639 /* join the thread. */
640 rc = llthread_alive(this);
641
642 if( rc == JOIN_ETIMEDOUT ){
643 lua_pushboolean(L, 1);
644 return 1;
645 }
646
647 if(rc == JOIN_OK){
648 lua_pushboolean(L, 0);
649 return 1;
650 }
651
652 {
653 char buf[ERROR_LEN];
654 strerror_r(errno, buf, ERROR_LEN);
655
656 /* llthread_cleanup_child(this); */
657
658 return fail(L, buf);
659 }
660
661}
662
595static int l_llthread_new(lua_State *L) { 663static int l_llthread_new(lua_State *L) {
596 size_t lua_code_len; const char *lua_code = luaL_checklstring(L, 1, &lua_code_len); 664 size_t lua_code_len; const char *lua_code = luaL_checklstring(L, 1, &lua_code_len);
597 llthread_t **this = lutil_newudatap(L, llthread_t*, LLTHREAD_TAG); 665 llthread_t **this = lutil_newudatap(L, llthread_t*, LLTHREAD_TAG);
@@ -605,6 +673,7 @@ static int l_llthread_new(lua_State *L) {
605static const struct luaL_Reg l_llthread_meth[] = { 673static const struct luaL_Reg l_llthread_meth[] = {
606 {"start", l_llthread_start }, 674 {"start", l_llthread_start },
607 {"join", l_llthread_join }, 675 {"join", l_llthread_join },
676 {"alive", l_llthread_alive },
608 {"__gc", l_llthread_delete }, 677 {"__gc", l_llthread_delete },
609 678
610 {NULL, NULL} 679 {NULL, NULL}