diff --git a/README.md b/README.md index 5f89ec8..6fee2eb 100644 --- a/README.md +++ b/README.md @@ -3,4 +3,22 @@ About A simple low-level Lua wrapper for pthreads. +Example usage +============= + + local llthreads = require"llthreads" + + local thread_code = [[ + -- print thread's parameter. + print("CHILD: received params:", ...) + -- return all thread's parameters back to the parent thread. + return ... + ]] + + -- create child thread. + local thread = llthreads.new(thread_code, "number:", 1234, "nil:", nil, "bool:", true) + -- start joinable child thread. + assert(thread:start()) + print("PARENT: child returned: ", thread:join()) + diff --git a/src/pre_generated-llthreads.nobj.c b/src/pre_generated-llthreads.nobj.c index 6bd8c63..af103e2 100644 --- a/src/pre_generated-llthreads.nobj.c +++ b/src/pre_generated-llthreads.nobj.c @@ -633,9 +633,9 @@ static int nobj_try_loading_ffi(lua_State *L, const char *ffi_mod_name, typedef enum { TSTATE_NONE = 0, - TSTATE_STARTED = 1<<1, - TSTATE_DETACHED = 1<<2, - TSTATE_JOINED = 1<<3, + TSTATE_STARTED = 1<<0, + TSTATE_DETACHED = 1<<1, + TSTATE_JOINED = 1<<2, } Lua_TState; typedef struct Lua_LLThread_child { @@ -827,7 +827,6 @@ static int llthread_move_values(lua_State *from_L, lua_State *to_L, int idx, int } ++nvalues; } -printf("copied nvalues=%d, top=%d\n", nvalues, top); return nvalues; } @@ -904,14 +903,22 @@ static int Lua_LLThread__delete__meth(lua_State *L) { static int Lua_LLThread__start__meth(lua_State *L) { Lua_LLThread * this_idx1 = obj_type_Lua_LLThread_check(L,1); bool start_detached_idx2 = lua_toboolean(L,2); - int rc_idx1 = 0; + bool res_idx1 = 0; + int rc; + if(this_idx1->state != TSTATE_NONE) { - return luaL_error(L, "Thread already started."); + lua_pushboolean(L, 0); /* false */ + lua_pushliteral(L, "Thread already started."); + return 2; } -printf("llthread_start(): start_detached=%d\n", start_detached_idx2); - rc_idx1 = llthread_start(this_idx1, start_detached_idx2); + if((rc = llthread_start(this_idx1, start_detached_idx2)) != 0) { + lua_pushboolean(L, 0); /* false */ + lua_pushstring(L, strerror(rc)); + return 2; + } + res_idx1 = true; - lua_pushinteger(L, rc_idx1); + lua_pushboolean(L, res_idx1); return 1; } @@ -919,17 +926,24 @@ printf("llthread_start(): start_detached=%d\n", start_detached_idx2); static int Lua_LLThread__join__meth(lua_State *L) { Lua_LLThread * this_idx1 = obj_type_Lua_LLThread_check(L,1); bool res_idx1 = 0; + const char * err_msg_idx2 = NULL; Lua_LLThread_child *child; int rc; if((this_idx1->state & TSTATE_STARTED) == 0) { - return luaL_error(L, "Can't join a thread that hasn't be started."); + lua_pushboolean(L, 0); /* false */ + lua_pushliteral(L, "Can't join a thread that hasn't be started."); + return 2; } - if((this_idx1->state & TSTATE_DETACHED) == 1) { - return luaL_error(L, "Can't join a thread that has been detached."); + if((this_idx1->state & TSTATE_DETACHED) == TSTATE_DETACHED) { + lua_pushboolean(L, 0); /* false */ + lua_pushliteral(L, "Can't join a thread that has been detached."); + return 2; } - if((this_idx1->state & TSTATE_JOINED) == 1) { - return luaL_error(L, "Can't join a thread that has already been joined."); + if((this_idx1->state & TSTATE_JOINED) == TSTATE_JOINED) { + lua_pushboolean(L, 0); /* false */ + lua_pushliteral(L, "Can't join a thread that has already been joined."); + return 2; } /* join the thread. */ rc = llthread_join(this_idx1); @@ -951,10 +965,12 @@ static int Lua_LLThread__join__meth(lua_State *L) { return top - 1; } else { res_idx1 = false; + err_msg_idx2 = strerror(rc); } lua_pushboolean(L, res_idx1); - return 1; + lua_pushstring(L, err_msg_idx2); + return 2; } /* method: new */ diff --git a/src/thread.nobj.lua b/src/thread.nobj.lua index fdfa2c0..0cadf75 100644 --- a/src/thread.nobj.lua +++ b/src/thread.nobj.lua @@ -21,9 +21,9 @@ local Lua_LLThread_type = [[ typedef enum { TSTATE_NONE = 0, - TSTATE_STARTED = 1<<1, - TSTATE_DETACHED = 1<<2, - TSTATE_JOINED = 1<<3, + TSTATE_STARTED = 1<<0, + TSTATE_DETACHED = 1<<1, + TSTATE_JOINED = 1<<2, } Lua_TState; typedef struct Lua_LLThread_child { @@ -293,7 +293,9 @@ static Lua_LLThread *llthread_create(lua_State *L, const char *code, size_t code ]], c_source[[ if(${this}->state != TSTATE_NONE) { - return luaL_error(L, "Thread already started."); + lua_pushboolean(L, 0); /* false */ + lua_pushliteral(L, "Thread already started."); + return 2; } if((rc = llthread_start(${this}, ${start_detached})) != 0) { lua_pushboolean(L, 0); /* false */ @@ -312,13 +314,19 @@ static Lua_LLThread *llthread_create(lua_State *L, const char *code, size_t code ]], c_source[[ if((${this}->state & TSTATE_STARTED) == 0) { - return luaL_error(L, "Can't join a thread that hasn't be started."); + lua_pushboolean(L, 0); /* false */ + lua_pushliteral(L, "Can't join a thread that hasn't be started."); + return 2; } - if((${this}->state & TSTATE_DETACHED) == 1) { - return luaL_error(L, "Can't join a thread that has been detached."); + if((${this}->state & TSTATE_DETACHED) == TSTATE_DETACHED) { + lua_pushboolean(L, 0); /* false */ + lua_pushliteral(L, "Can't join a thread that has been detached."); + return 2; } - if((${this}->state & TSTATE_JOINED) == 1) { - return luaL_error(L, "Can't join a thread that has already been joined."); + if((${this}->state & TSTATE_JOINED) == TSTATE_JOINED) { + lua_pushboolean(L, 0); /* false */ + lua_pushliteral(L, "Can't join a thread that has already been joined."); + return 2; } /* join the thread. */ rc = llthread_join(${this}); diff --git a/tests/test_llthreads.lua b/tests/test_llthreads.lua index e241606..551801f 100644 --- a/tests/test_llthreads.lua +++ b/tests/test_llthreads.lua @@ -20,19 +20,34 @@ local llthreads = require"llthreads" +local function detached_thread(...) + local thread = llthreads.new([[ print("print_detached_thread:", ...) ]], ...) + -- start detached thread + assert(thread:start(true)) + return thread +end + local function print_thread(...) - return llthreads.new([[ return print("print_thread:", ...) ]], ...) + local thread = llthreads.new([[ return print("print_thread:", ...) ]], ...) + -- start joinable thread + assert(thread:start()) + return thread end local function pass_through_thread(...) - return llthreads.new([[ return "pass_thread:", ... ]], ...) + local thread = llthreads.new([[ return "pass_thread:", ... ]], ...) + -- start joinable thread + assert(thread:start()) + return thread end -local thread = print_thread("number:", 1234, "nil:", nil, "bool:", true) -print(thread:start()) -print(thread:join()) +local thread1 = detached_thread("number:", 1234, "nil:", nil, "bool:", true) + +local thread2 = print_thread("number:", 1234, "nil:", nil, "bool:", true) +print(thread2:join()) + +local thread3 = pass_through_thread("number:", 1234, "nil:", nil, "bool:", true) +print("resuls:", thread3:join()) -local thread = pass_through_thread("number:", 1234, "nil:", nil, "bool:", true) -print(thread:start()) -print("resuls:", thread:join()) +os.execute("sleep 2");