diff options
| author | ruki <[email protected]> | 2025-09-02 10:16:24 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2025-09-02 10:16:24 +0800 |
| commit | 148501afafa5e9e05da7a54bc804880d6c415849 (patch) | |
| tree | f5cbcee2b05d4b836478a45698c8a42b43ea38b7 /core/src | |
| parent | 90b7015682c5523dfa252ebfbab6ed16b3e4b16a (diff) | |
| parent | 37a499eeb5fd84be4ac83d639211e18e55dccd32 (diff) | |
Merge pull request #6324 from xmake-io/thread
Add native thread support
Diffstat (limited to 'core/src')
55 files changed, 2662 insertions, 76 deletions
diff --git a/core/src/tbox/tbox b/core/src/tbox/tbox -Subproject 7af204577394bb0364eef245f33e7cea6eed059 +Subproject 91a110d061d6486a7a0826919e0c60caf7586a3 diff --git a/core/src/xmake/engine.c b/core/src/xmake/engine.c index 69853c1f9..ee07da6ea 100644 --- a/core/src/xmake/engine.c +++ b/core/src/xmake/engine.c @@ -29,6 +29,7 @@ * includes */ #include "xmake.h" +#include "io/poller.h" #if defined(TB_CONFIG_OS_WINDOWS) # include <windows.h> # include <io.h> @@ -64,6 +65,11 @@ # include "lz4/prefix.h" #endif +// for lua +#ifndef USE_LUAJIT +# include "../../lua/lua/lstate.h" +#endif + /* ////////////////////////////////////////////////////////////////////////////////////// * macros */ @@ -95,6 +101,10 @@ typedef struct __xm_engine_t // the engine name tb_char_t name[64]; + // the io poller + tb_poller_ref_t poller; + xm_poller_state_t poller_state; + #ifdef XM_EMBED_ENABLE // the temporary directory tb_char_t tmpdir[TB_PATH_MAXN]; @@ -329,6 +339,52 @@ tb_int_t xm_utils_bin2c(lua_State* lua); tb_int_t xm_lua_curses_register(lua_State* lua, tb_char_t const* module); #endif +// the thread functions +tb_int_t xm_thread_init(lua_State* lua); +tb_int_t xm_thread_exit(lua_State* lua); +tb_int_t xm_thread_wait(lua_State* lua); +tb_int_t xm_thread_suspend(lua_State* lua); +tb_int_t xm_thread_resume(lua_State* lua); + +// the thread/mutex functions +tb_int_t xm_thread_mutex_init(lua_State* lua); +tb_int_t xm_thread_mutex_exit(lua_State* lua); +tb_int_t xm_thread_mutex_lock(lua_State* lua); +tb_int_t xm_thread_mutex_trylock(lua_State* lua); +tb_int_t xm_thread_mutex_unlock(lua_State* lua); +tb_int_t xm_thread_mutex_incref(lua_State* lua); + +// the thread/event functions +tb_int_t xm_thread_event_init(lua_State* lua); +tb_int_t xm_thread_event_exit(lua_State* lua); +tb_int_t xm_thread_event_post(lua_State* lua); +tb_int_t xm_thread_event_wait(lua_State* lua); +tb_int_t xm_thread_event_incref(lua_State* lua); + +// the thread/semaphore functions +tb_int_t xm_thread_semaphore_init(lua_State* lua); +tb_int_t xm_thread_semaphore_exit(lua_State* lua); +tb_int_t xm_thread_semaphore_post(lua_State* lua); +tb_int_t xm_thread_semaphore_wait(lua_State* lua); +tb_int_t xm_thread_semaphore_incref(lua_State* lua); + +// the thread/queue functions +tb_int_t xm_thread_queue_init(lua_State* lua); +tb_int_t xm_thread_queue_exit(lua_State* lua); +tb_int_t xm_thread_queue_size(lua_State* lua); +tb_int_t xm_thread_queue_clear(lua_State* lua); +tb_int_t xm_thread_queue_incref(lua_State* lua); +tb_int_t xm_thread_queue_push(lua_State* lua); +tb_int_t xm_thread_queue_pop(lua_State* lua); + +// the thread/sharedata functions +tb_int_t xm_thread_sharedata_init(lua_State* lua); +tb_int_t xm_thread_sharedata_exit(lua_State* lua); +tb_int_t xm_thread_sharedata_clear(lua_State* lua); +tb_int_t xm_thread_sharedata_incref(lua_State* lua); +tb_int_t xm_thread_sharedata_set(lua_State* lua); +tb_int_t xm_thread_sharedata_get_(lua_State* lua); + // open cjson __tb_extern_c_enter__ tb_int_t luaopen_cjson(lua_State *l); @@ -615,6 +671,46 @@ static luaL_Reg const g_utils_functions[] = , { tb_null, tb_null } }; +// the thread functions +static luaL_Reg const g_thread_functions[] = +{ + { "thread_init", xm_thread_init } +, { "thread_exit", xm_thread_exit } +, { "thread_wait", xm_thread_wait } +, { "thread_resume", xm_thread_resume } +, { "thread_suspend", xm_thread_suspend } +, { "mutex_init", xm_thread_mutex_init } +, { "mutex_exit", xm_thread_mutex_exit } +, { "mutex_lock", xm_thread_mutex_lock } +, { "mutex_trylock", xm_thread_mutex_trylock } +, { "mutex_unlock", xm_thread_mutex_unlock } +, { "mutex_incref", xm_thread_mutex_incref } +, { "event_init", xm_thread_event_init } +, { "event_exit", xm_thread_event_exit } +, { "event_post", xm_thread_event_post } +, { "event_wait", xm_thread_event_wait } +, { "event_incref", xm_thread_event_incref } +, { "semaphore_init", xm_thread_semaphore_init } +, { "semaphore_exit", xm_thread_semaphore_exit } +, { "semaphore_post", xm_thread_semaphore_post } +, { "semaphore_wait", xm_thread_semaphore_wait } +, { "semaphore_incref", xm_thread_semaphore_incref } +, { "queue_init", xm_thread_queue_init } +, { "queue_exit", xm_thread_queue_exit } +, { "queue_size", xm_thread_queue_size } +, { "queue_clear", xm_thread_queue_clear } +, { "queue_incref", xm_thread_queue_incref } +, { "queue_push", xm_thread_queue_push } +, { "queue_pop", xm_thread_queue_pop } +, { "sharedata_init", xm_thread_sharedata_init } +, { "sharedata_exit", xm_thread_sharedata_exit } +, { "sharedata_clear", xm_thread_sharedata_clear } +, { "sharedata_incref", xm_thread_sharedata_incref } +, { "sharedata_set", xm_thread_sharedata_set } +, { "sharedata_get", xm_thread_sharedata_get_ } +, { tb_null, tb_null } +}; + // the lua global instance for signal handler static lua_State* g_lua = tb_null; @@ -1189,6 +1285,7 @@ static tb_void_t xm_engine_init_signal(xm_engine_t* engine) } #if XM_HOOK_LUA_MEMALLOC +// udata is unused, it has been used by engine. see xm_engine_bind_to_lua() static tb_pointer_t xm_engine_lua_realloc(tb_pointer_t udata, tb_pointer_t data, size_t osize, size_t nsize) { tb_pointer_t ptr = tb_null; @@ -1319,6 +1416,17 @@ static tb_bool_t xm_engine_extract_programfiles(xm_engine_t* engine, tb_char_t c } #endif +static tb_void_t xm_engine_bind_to_lua(lua_State* lua, xm_engine_t* engine) +{ +#ifdef USE_LUAJIT + lua_pushlightuserdata(lua, engine); + lua_setglobal(lua, "__global_engine"); +#else + global_State* g = G(lua); + g->ud = engine; +#endif +} + /* ////////////////////////////////////////////////////////////////////////////////////// * implementation */ @@ -1340,8 +1448,8 @@ xm_engine_ref_t xm_engine_init(tb_char_t const* name, xm_engine_lni_initalizer_c tb_assert_and_check_break(engine->lua); #if XM_HOOK_LUA_MEMALLOC - // hook lua memmory - lua_setallocf(engine->lua, xm_engine_lua_realloc, engine->lua); + // hook lua memmory, @note we cannot set udata argument, xm_engine_bind_to_lua() has used it. + lua_setallocf(engine->lua, xm_engine_lua_realloc, tb_null); #endif // open lua libraries @@ -1405,6 +1513,9 @@ xm_engine_ref_t xm_engine_init(tb_char_t const* name, xm_engine_lni_initalizer_c // bind utils functions xm_lua_register(engine->lua, "utils", g_utils_functions); + // bind thread functions + xm_lua_register(engine->lua, "thread", g_thread_functions); + #ifdef XM_CONFIG_API_HAVE_CURSES // bind curses xm_lua_curses_register(engine->lua, "curses"); @@ -1416,6 +1527,9 @@ xm_engine_ref_t xm_engine_init(tb_char_t const* name, xm_engine_lni_initalizer_c lua_setglobal(engine->lua, "cjson"); #endif + // bind engine to lua + xm_engine_bind_to_lua(engine->lua, engine); + // init host xm_engine_init_host(engine); @@ -1510,6 +1624,10 @@ tb_void_t xm_engine_exit(xm_engine_ref_t self) if (engine->lua) lua_close(engine->lua); engine->lua = tb_null; + // exit poller + if (engine->poller) tb_poller_exit(engine->poller); + engine->poller = tb_null; + // exit it tb_free(engine); } @@ -1600,6 +1718,33 @@ tb_void_t xm_engine_add_embedfiles(xm_engine_ref_t self, tb_byte_t const* data, engine->embedcount++; } #endif +lua_State* xm_engine_lua(xm_engine_ref_t self) +{ + // check + xm_engine_t* engine = (xm_engine_t*)self; + tb_assert_and_check_return_val(engine, tb_null); + + return engine->lua; +} +tb_poller_ref_t xm_engine_poller(xm_engine_ref_t self) +{ + // check + xm_engine_t* engine = (xm_engine_t*)self; + tb_assert_and_check_return_val(engine, tb_null); + + if (!engine->poller) + { + // init poller + engine->poller_state.lua = engine->lua; + tb_poller_ref_t poller = tb_poller_init(&engine->poller_state); + tb_assert_and_check_return_val(poller, tb_null); + + // attach poller to the current thread + tb_poller_attach(poller); + engine->poller = poller; + } + return engine->poller; +} tb_int_t xm_engine_run(tb_char_t const* name, tb_int_t argc, tb_char_t** argv, tb_char_t** taskargv, xm_engine_lni_initalizer_cb_t lni_initalizer) { tb_int_t ok = -1; @@ -1615,4 +1760,16 @@ tb_int_t xm_engine_run(tb_char_t const* name, tb_int_t argc, tb_char_t** argv, t } return ok; } +xm_engine_ref_t xm_engine_get(lua_State* lua) +{ + tb_assert_and_check_return_val(lua, tb_null); + +#ifdef USE_LUAJIT + lua_getglobal(lua, "__global_engine"); + return (xm_engine_ref_t)lua_touserdata(lua, -1); +#else + global_State* g = G(lua); + return (xm_engine_ref_t)g->ud; +#endif +} diff --git a/core/src/xmake/engine.h b/core/src/xmake/engine.h index 89344cef1..04ef958d9 100644 --- a/core/src/xmake/engine.h +++ b/core/src/xmake/engine.h @@ -81,12 +81,28 @@ tb_void_t xm_engine_register(xm_engine_ref_t engine, tb_char_t /*! add the embed files * - * @param name the engine name + * @param engine the engine * @param data the embedfiles data * @param size the data size */ tb_void_t xm_engine_add_embedfiles(xm_engine_ref_t engine, tb_byte_t const* data, tb_size_t size); +/* get lua state from engine + * + * @param engine the engine + * + * @return the lua state + */ +lua_State* xm_engine_lua(xm_engine_ref_t engine); + +/* get poller from engine + * + * @param engine the engine + * + * @return the poller + */ +tb_poller_ref_t xm_engine_poller(xm_engine_ref_t engine); + /*! run main entry of the engine singleton * * @param name the engine name @@ -99,6 +115,14 @@ tb_void_t xm_engine_add_embedfiles(xm_engine_ref_t engine, tb_ */ tb_int_t xm_engine_run(tb_char_t const* name, tb_int_t argc, tb_char_t** argv, tb_char_t** taskargv, xm_engine_lni_initalizer_cb_t lni_initalizer); +/*! get engine from the given lua state + * + * @param lua the lua state + * + * @return the engine + */ +xm_engine_ref_t xm_engine_get(lua_State* lua); + /* ////////////////////////////////////////////////////////////////////////////////////// * extern */ diff --git a/core/src/xmake/engine_pool.c b/core/src/xmake/engine_pool.c new file mode 100644 index 000000000..78081399c --- /dev/null +++ b/core/src/xmake/engine_pool.c @@ -0,0 +1,107 @@ +/*!A cross-platform build utility based on Lua + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright (C) 2015-present, Xmake Open Source Community. + * + * @author ruki + * @file engine_pool.c + * + */ + +/* ////////////////////////////////////////////////////////////////////////////////////// + * trace + */ +#define TB_TRACE_MODULE_NAME "engine_pool" +#define TB_TRACE_MODULE_DEBUG (0) + +/* ////////////////////////////////////////////////////////////////////////////////////// + * includes + */ +#include "xmake.h" +#include "engine.h" +#include "engine_pool.h" + +/* ////////////////////////////////////////////////////////////////////////////////////// + * macros + */ + +// the max engine pool count +#define XM_ENGINE_POOL_MAXN (128) + +// the singleton type of engine pool +#define XM_ENGINE_POOL (TB_SINGLETON_TYPE_USER + 4) + +/* ////////////////////////////////////////////////////////////////////////////////////// + * private implementation + */ +static tb_handle_t xm_engine_pool_instance_init(tb_cpointer_t* ppriv) +{ + xm_engine_pool_ref_t engine_pool = xm_engine_pool_init(); + tb_assert_and_check_return_val(engine_pool, tb_null); + + return (tb_handle_t)engine_pool; +} + +static tb_void_t xm_engine_pool_instance_exit(tb_handle_t engine_pool, tb_cpointer_t priv) +{ + if (engine_pool) xm_engine_pool_exit((xm_engine_pool_ref_t)engine_pool); +} + +/* ////////////////////////////////////////////////////////////////////////////////////// + * implementation + */ +xm_engine_pool_ref_t xm_engine_pool() +{ + return (xm_engine_pool_ref_t)tb_singleton_instance(XM_ENGINE_POOL, xm_engine_pool_instance_init, xm_engine_pool_instance_exit, tb_null, tb_null); +} + +xm_engine_pool_ref_t xm_engine_pool_init() +{ + return tb_single_list_init(0, tb_element_ptr(tb_null, tb_null)); +} + +tb_void_t xm_engine_pool_exit(xm_engine_pool_ref_t engine_pool) +{ + if (engine_pool) + { + tb_for_all (xm_engine_ref_t, engine, engine_pool) + { + if (engine) + xm_engine_exit(engine); + } + tb_single_list_exit(engine_pool); + } +} + +xm_engine_ref_t xm_engine_pool_alloc(xm_engine_pool_ref_t engine_pool) +{ + xm_engine_ref_t engine = tb_null; + if (tb_single_list_size(engine_pool) > 0) + { + engine = (xm_engine_ref_t)tb_single_list_head(engine_pool); + tb_single_list_remove_head(engine_pool); + } + return engine; +} + +tb_bool_t xm_engine_pool_free(xm_engine_pool_ref_t engine_pool, xm_engine_ref_t engine) +{ + if (tb_single_list_size(engine_pool) < XM_ENGINE_POOL_MAXN) + { + tb_single_list_insert_tail(engine_pool, engine); + return tb_true; + } + return tb_false; +} + diff --git a/core/src/xmake/engine_pool.h b/core/src/xmake/engine_pool.h new file mode 100644 index 000000000..853856d1c --- /dev/null +++ b/core/src/xmake/engine_pool.h @@ -0,0 +1,82 @@ +/*!A cross-platform build utility based on Lua + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright (C) 2015-present, Xmake Open Source Community. + * + * @author ruki + * @file engine_pool.h + * + */ +#ifndef XM_ENGINE_POOL_H +#define XM_ENGINE_POOL_H + +/* ////////////////////////////////////////////////////////////////////////////////////// + * includes + */ +#include "prefix.h" + +/* ////////////////////////////////////////////////////////////////////////////////////// + * extern + */ +__tb_extern_c_enter__ + +/* ////////////////////////////////////////////////////////////////////////////////////// + * types + */ + +/// the xmake engine pool type +typedef tb_single_list_ref_t xm_engine_pool_ref_t; + +/* ////////////////////////////////////////////////////////////////////////////////////// + * interfaces + */ + +// get the engine pool singleton +xm_engine_pool_ref_t xm_engine_pool(tb_void_t); + +/*! init the engine_pool + * + * @return the engine pool + */ +xm_engine_pool_ref_t xm_engine_pool_init(tb_void_t); + +/*! exit the engine_pool + * + * @param engine_pool the engine_pool + */ +tb_void_t xm_engine_pool_exit(xm_engine_pool_ref_t engine_pool); + +/*! alloc a engine from the engine_pool + * + * @param engine_pool the engine_pool + * + * @return the engine + */ +xm_engine_ref_t xm_engine_pool_alloc(xm_engine_pool_ref_t engine_pool); + +/*! free a engine to the engine_pool + * + * @param engine_pool the engine_pool + * @param engine the engine + * + * @return tb_true or tb_false + */ +tb_bool_t xm_engine_pool_free(xm_engine_pool_ref_t engine_pool, xm_engine_ref_t engine); + +/* ////////////////////////////////////////////////////////////////////////////////////// + * extern + */ +__tb_extern_c_leave__ + +#endif diff --git a/core/src/xmake/io/pipe_close.c b/core/src/xmake/io/pipe_close.c index 6f50cbf67..062e7009d 100644 --- a/core/src/xmake/io/pipe_close.c +++ b/core/src/xmake/io/pipe_close.c @@ -41,11 +41,11 @@ tb_int_t xm_io_pipe_close(lua_State* lua) tb_assert_and_check_return_val(lua, 0); // check pipe? - if (!xm_lua_ispointer(lua, 1)) + if (!xm_pipe_file_is_valid(lua, 1)) return 0; // get the pipe file - tb_pipe_file_ref_t pipefile = (tb_pipe_file_ref_t)xm_lua_topointer(lua, 1); + tb_pipe_file_ref_t pipefile = xm_pipe_file_get(lua, 1); tb_check_return_val(pipefile, 0); // exit pipe file diff --git a/core/src/xmake/io/pipe_read.c b/core/src/xmake/io/pipe_read.c index d75547714..cb3457fec 100644 --- a/core/src/xmake/io/pipe_read.c +++ b/core/src/xmake/io/pipe_read.c @@ -41,7 +41,7 @@ tb_int_t xm_io_pipe_read(lua_State* lua) tb_assert_and_check_return_val(lua, 0); // check pipe file - if (!xm_lua_ispointer(lua, 1)) + if (!xm_pipe_file_is_valid(lua, 1)) { lua_pushinteger(lua, -1); lua_pushliteral(lua, "invalid pipe file!"); @@ -49,7 +49,7 @@ tb_int_t xm_io_pipe_read(lua_State* lua) } // get pipe file - tb_pipe_file_ref_t pipefile = (tb_pipe_file_ref_t)xm_lua_topointer(lua, 1); + tb_pipe_file_ref_t pipefile = xm_pipe_file_get(lua, 1); tb_check_return_val(pipefile, 0); // get data diff --git a/core/src/xmake/io/pipe_wait.c b/core/src/xmake/io/pipe_wait.c index 7de310425..f39220d41 100644 --- a/core/src/xmake/io/pipe_wait.c +++ b/core/src/xmake/io/pipe_wait.c @@ -41,11 +41,11 @@ tb_int_t xm_io_pipe_wait(lua_State* lua) tb_assert_and_check_return_val(lua, 0); // check pipe? - if (!xm_lua_ispointer(lua, 1)) + if (!xm_pipe_file_is_valid(lua, 1)) return 0; // get pipe file - tb_pipe_file_ref_t pipefile = (tb_pipe_file_ref_t)xm_lua_topointer(lua, 1); + tb_pipe_file_ref_t pipefile = xm_pipe_file_get(lua, 1); tb_check_return_val(pipefile, 0); // get events diff --git a/core/src/xmake/io/pipe_write.c b/core/src/xmake/io/pipe_write.c index 2ea0c69fe..140894428 100644 --- a/core/src/xmake/io/pipe_write.c +++ b/core/src/xmake/io/pipe_write.c @@ -41,7 +41,7 @@ tb_int_t xm_io_pipe_write(lua_State* lua) tb_assert_and_check_return_val(lua, 0); // check pipe - if (!xm_lua_ispointer(lua, 1)) + if (!xm_pipe_file_is_valid(lua, 1)) { lua_pushinteger(lua, -1); lua_pushliteral(lua, "invalid pipe file!"); @@ -49,7 +49,7 @@ tb_int_t xm_io_pipe_write(lua_State* lua) } // get pipe file - tb_pipe_file_ref_t pipefile = (tb_pipe_file_ref_t)xm_lua_topointer(lua, 1); + tb_pipe_file_ref_t pipefile = xm_pipe_file_get(lua, 1); tb_check_return_val(pipefile, 0); // get data and size diff --git a/core/src/xmake/io/poller.c b/core/src/xmake/io/poller.c index 77c35e639..7700c6858 100644 --- a/core/src/xmake/io/poller.c +++ b/core/src/xmake/io/poller.c @@ -29,37 +29,17 @@ * includes */ #include "poller.h" - -/* ////////////////////////////////////////////////////////////////////////////////////// - * macros - */ - -// the singleton type of poller -#define XM_IO_POLLER (TB_SINGLETON_TYPE_USER + 4) - -/* ////////////////////////////////////////////////////////////////////////////////////// - * private implementation - */ -static tb_handle_t xm_io_poller_instance_init(tb_cpointer_t* ppriv) -{ - // init poller - tb_poller_ref_t poller = tb_poller_init(tb_null); - tb_assert_and_check_return_val(poller, tb_null); - - // attach poller to the current thread - tb_poller_attach(poller); - return (tb_handle_t)poller; -} -static tb_void_t xm_io_poller_instance_exit(tb_handle_t poller, tb_cpointer_t priv) -{ - if (poller) tb_poller_exit((tb_poller_ref_t)poller); -} +#include "../engine.h" /* ////////////////////////////////////////////////////////////////////////////////////// * implementation */ -tb_poller_ref_t xm_io_poller() +tb_poller_ref_t xm_io_poller(lua_State* lua) { - return (tb_poller_ref_t)tb_singleton_instance(XM_IO_POLLER, xm_io_poller_instance_init, xm_io_poller_instance_exit, tb_null, tb_null); + tb_poller_ref_t poller = tb_null; + xm_engine_ref_t engine = xm_engine_get(lua); + if (engine) poller = xm_engine_poller(engine); + tb_assert(poller); + return poller; } diff --git a/core/src/xmake/io/poller.h b/core/src/xmake/io/poller.h index 83252afd5..887fc25ba 100644 --- a/core/src/xmake/io/poller.h +++ b/core/src/xmake/io/poller.h @@ -27,6 +27,18 @@ #include "prefix.h" /* ////////////////////////////////////////////////////////////////////////////////////// + * types + */ + +// the poller state in wait events +typedef struct __xm_poller_state_t +{ + lua_State* lua; + tb_int_t events_count; + +}xm_poller_state_t; + +/* ////////////////////////////////////////////////////////////////////////////////////// * interfaces */ @@ -34,7 +46,7 @@ * * @return the io poller */ -tb_poller_ref_t xm_io_poller(tb_noarg_t); +tb_poller_ref_t xm_io_poller(lua_State* lua); #endif diff --git a/core/src/xmake/io/poller_insert.c b/core/src/xmake/io/poller_insert.c index b8890842a..e78c3c18f 100644 --- a/core/src/xmake/io/poller_insert.c +++ b/core/src/xmake/io/poller_insert.c @@ -64,7 +64,7 @@ tb_int_t xm_io_poller_insert(lua_State* lua) tb_poller_object_t object; object.type = otype; object.ref.ptr = cdata; - lua_pushboolean(lua, tb_poller_insert(xm_io_poller(), &object, events, cdata_str)); + lua_pushboolean(lua, tb_poller_insert(xm_io_poller(lua), &object, events, cdata_str)); return 1; } diff --git a/core/src/xmake/io/poller_modify.c b/core/src/xmake/io/poller_modify.c index e16f715d4..5ed858030 100644 --- a/core/src/xmake/io/poller_modify.c +++ b/core/src/xmake/io/poller_modify.c @@ -64,7 +64,7 @@ tb_int_t xm_io_poller_modify(lua_State* lua) tb_poller_object_t object; object.type = otype; object.ref.ptr = cdata; - lua_pushboolean(lua, tb_poller_modify(xm_io_poller(), &object, events, cdata_str)); + lua_pushboolean(lua, tb_poller_modify(xm_io_poller(lua), &object, events, cdata_str)); return 1; } diff --git a/core/src/xmake/io/poller_remove.c b/core/src/xmake/io/poller_remove.c index a0c67b9bc..3cad1aa0a 100644 --- a/core/src/xmake/io/poller_remove.c +++ b/core/src/xmake/io/poller_remove.c @@ -60,7 +60,7 @@ tb_int_t xm_io_poller_remove(lua_State* lua) tb_poller_object_t object; object.type = otype; object.ref.ptr = cdata; - lua_pushboolean(lua, tb_poller_remove(xm_io_poller(), &object)); + lua_pushboolean(lua, tb_poller_remove(xm_io_poller(lua), &object)); return 1; } diff --git a/core/src/xmake/io/poller_spank.c b/core/src/xmake/io/poller_spank.c index e7d0bfcaf..ac7207763 100644 --- a/core/src/xmake/io/poller_spank.c +++ b/core/src/xmake/io/poller_spank.c @@ -42,7 +42,7 @@ tb_int_t xm_io_poller_spank(lua_State* lua) tb_assert_and_check_return_val(lua, 0); // spank the poller, break the tb_poller_wait() and return all events - tb_poller_spak(xm_io_poller()); + tb_poller_spak(xm_io_poller(lua)); return 0; } diff --git a/core/src/xmake/io/poller_support.c b/core/src/xmake/io/poller_support.c index b26810a43..36ae52b34 100644 --- a/core/src/xmake/io/poller_support.c +++ b/core/src/xmake/io/poller_support.c @@ -45,7 +45,7 @@ tb_int_t xm_io_poller_support(lua_State* lua) tb_size_t events = (tb_size_t)luaL_checknumber(lua, 1); // support events for poller - lua_pushboolean(lua, tb_poller_support(xm_io_poller(), events)); + lua_pushboolean(lua, tb_poller_support(xm_io_poller(lua), events)); return 1; } diff --git a/core/src/xmake/io/poller_wait.c b/core/src/xmake/io/poller_wait.c index 01021d943..341893f74 100644 --- a/core/src/xmake/io/poller_wait.c +++ b/core/src/xmake/io/poller_wait.c @@ -32,46 +32,40 @@ #include "poller.h" /* ////////////////////////////////////////////////////////////////////////////////////// - * globals - */ - -// we need only one global lua state/poller in main thread, so it is thread-safe. -static lua_State* g_lua = tb_null; -static tb_int_t g_events_count = 0; - -/* ////////////////////////////////////////////////////////////////////////////////////// * private implementation */ static tb_void_t xm_io_poller_event(tb_poller_ref_t poller, tb_poller_object_ref_t object, tb_long_t events, tb_cpointer_t priv) { // check - tb_assert_and_check_return(g_lua); + xm_poller_state_t* state = (xm_poller_state_t*)tb_poller_priv(poller); + tb_assert_and_check_return(state && state->lua); // save object and events - lua_newtable(g_lua); - lua_pushinteger(g_lua, (tb_int_t)object->type); - lua_rawseti(g_lua, -2, 1); - if (priv) lua_pushstring(g_lua, (tb_char_t const*)priv); - else lua_pushlightuserdata(g_lua, object->ref.ptr); - lua_rawseti(g_lua, -2, 2); + lua_State* lua = state->lua; + lua_newtable(lua); + lua_pushinteger(lua, (tb_int_t)object->type); + lua_rawseti(lua, -2, 1); + if (priv) lua_pushstring(lua, (tb_char_t const*)priv); + else lua_pushlightuserdata(lua, object->ref.ptr); + lua_rawseti(lua, -2, 2); if (object->type == TB_POLLER_OBJECT_FWATCHER) { - lua_newtable(g_lua); + lua_newtable(lua); tb_fwatcher_event_t* event = (tb_fwatcher_event_t*)events; if (event) { - lua_pushstring(g_lua, "path"); - lua_pushstring(g_lua, event->filepath); - lua_settable(g_lua, -3); + lua_pushstring(lua, "path"); + lua_pushstring(lua, event->filepath); + lua_settable(lua, -3); - lua_pushstring(g_lua, "type"); - lua_pushinteger(g_lua, event->event); - lua_settable(g_lua, -3); + lua_pushstring(lua, "type"); + lua_pushinteger(lua, event->event); + lua_settable(lua, -3); } } - else lua_pushinteger(g_lua, (tb_int_t)events); - lua_rawseti(g_lua, -2, 3); - lua_rawseti(g_lua, -2, ++g_events_count); + else lua_pushinteger(lua, (tb_int_t)events); + lua_rawseti(lua, -2, 3); + lua_rawseti(lua, -2, ++state->events_count); } /* ////////////////////////////////////////////////////////////////////////////////////// @@ -82,18 +76,19 @@ static tb_void_t xm_io_poller_event(tb_poller_ref_t poller, tb_poller_object_ref tb_int_t xm_io_poller_wait(lua_State* lua) { // check - tb_assert_and_check_return_val(lua, 0); + tb_poller_ref_t poller = xm_io_poller(lua); + tb_assert_and_check_return_val(poller && lua, 0); // get timeout tb_long_t timeout = (tb_long_t)luaL_checknumber(lua, 1); - // pass lua and count to the events callback - g_lua = lua; - g_events_count = 0; + // reset events count + xm_poller_state_t* state = (xm_poller_state_t*)tb_poller_priv(poller); + state->events_count = 0; // wait it lua_newtable(lua); - tb_long_t count = tb_poller_wait(xm_io_poller(), xm_io_poller_event, timeout); + tb_long_t count = tb_poller_wait(poller, xm_io_poller_event, timeout); if (count > 0) { lua_pushinteger(lua, (tb_int_t)count); diff --git a/core/src/xmake/io/prefix.h b/core/src/xmake/io/prefix.h index 7d8a8405b..ec2cc7216 100644 --- a/core/src/xmake/io/prefix.h +++ b/core/src/xmake/io/prefix.h @@ -94,6 +94,21 @@ typedef struct __xm_io_file_t } xm_io_file_t; +// check pipe file +static __tb_inline__ tb_bool_t xm_pipe_file_is_valid(lua_State* lua, tb_int_t index) +{ + return xm_lua_ispointer(lua, index) || xm_lua_isinteger(lua, index); +} + +// get the pipe file from arguments +static __tb_inline__ tb_pipe_file_ref_t xm_pipe_file_get(lua_State* lua, tb_int_t index) +{ + tb_pipe_file_ref_t pipe_file = tb_null; + if (xm_lua_isinteger(lua, index)) pipe_file = (tb_pipe_file_ref_t)(tb_size_t)(tb_long_t)lua_tointeger(lua, index); + else if (xm_lua_ispointer(lua, index)) pipe_file = (tb_pipe_file_ref_t)xm_lua_topointer(lua, index); + return pipe_file; +} + #endif diff --git a/core/src/xmake/io/socket_close.c b/core/src/xmake/io/socket_close.c index fca95c186..a424a707f 100644 --- a/core/src/xmake/io/socket_close.c +++ b/core/src/xmake/io/socket_close.c @@ -50,8 +50,6 @@ tb_int_t xm_io_socket_close(lua_State* lua) // exit socket lua_pushboolean(lua, tb_socket_exit(sock)); - - // ok return 1; } diff --git a/core/src/xmake/thread/event_exit.c b/core/src/xmake/thread/event_exit.c new file mode 100644 index 000000000..54e977068 --- /dev/null +++ b/core/src/xmake/thread/event_exit.c @@ -0,0 +1,55 @@ +/*!A cross-platform build utility based on Lua + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright (C) 2015-present, Xmake Open Source Community. + * + * @author ruki + * @file thread_event_exit.c + * + */ + +/* ////////////////////////////////////////////////////////////////////////////////////// + * trace + */ +#define TB_TRACE_MODULE_NAME "thread_event" +#define TB_TRACE_MODULE_DEBUG (0) + +/* ////////////////////////////////////////////////////////////////////////////////////// + * includes + */ +#include "prefix.h" + +/* ////////////////////////////////////////////////////////////////////////////////////// + * implementation + */ +tb_int_t xm_thread_event_exit(lua_State* lua) +{ + tb_assert_and_check_return_val(lua, 0); + + xm_thread_event_t* thread_event = xm_thread_event_get(lua, 1); + tb_assert_and_check_return_val(thread_event && thread_event->handle, 0); + + if (tb_atomic_fetch_and_sub(&thread_event->refn, 1) == 1) + { + if (thread_event->handle) + { + tb_event_exit(thread_event->handle); + thread_event->handle = tb_null; + } + tb_free(thread_event); + } + lua_pushboolean(lua, tb_true); + return 1; +} + diff --git a/core/src/xmake/thread/event_incref.c b/core/src/xmake/thread/event_incref.c new file mode 100644 index 000000000..ff8b658d9 --- /dev/null +++ b/core/src/xmake/thread/event_incref.c @@ -0,0 +1,46 @@ +/*!A cross-platform build utility based on Lua + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright (C) 2015-present, Xmake Open Source Community. + * + * @author ruki + * @file thread_event_incref.c + * + */ + +/* ////////////////////////////////////////////////////////////////////////////////////// + * trace + */ +#define TB_TRACE_MODULE_NAME "thread_event" +#define TB_TRACE_MODULE_DEBUG (0) + +/* ////////////////////////////////////////////////////////////////////////////////////// + * includes + */ +#include "prefix.h" + +/* ////////////////////////////////////////////////////////////////////////////////////// + * implementation + */ +tb_int_t xm_thread_event_incref(lua_State* lua) +{ + tb_assert_and_check_return_val(lua, 0); + + xm_thread_event_t* thread_event = xm_thread_event_get(lua, 1); + tb_assert_and_check_return_val(thread_event && thread_event->handle, 0); + + lua_pushboolean(lua, tb_atomic_fetch_and_add(&thread_event->refn, 1) >= 1); + return 1; +} + diff --git a/core/src/xmake/thread/event_init.c b/core/src/xmake/thread/event_init.c new file mode 100644 index 000000000..942537718 --- /dev/null +++ b/core/src/xmake/thread/event_init.c @@ -0,0 +1,70 @@ +/*!A cross-platform build utility based on Lua + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright (C) 2015-present, Xmake Open Source Community. + * + * @author ruki + * @file event_init.c + * + */ + +/* ////////////////////////////////////////////////////////////////////////////////////// + * trace + */ +#define TB_TRACE_MODULE_NAME "thread_event" +#define TB_TRACE_MODULE_DEBUG (0) + +/* ////////////////////////////////////////////////////////////////////////////////////// + * includes + */ +#include "prefix.h" + +/* ////////////////////////////////////////////////////////////////////////////////////// + * implementation + */ +tb_int_t xm_thread_event_init(lua_State* lua) +{ + tb_assert_and_check_return_val(lua, 0); + + tb_bool_t ok = tb_false; + xm_thread_event_t* thread_event = tb_null; + do + { + thread_event = tb_malloc0_type(xm_thread_event_t); + tb_assert_and_check_break(thread_event); + + thread_event->refn = 1; + thread_event->handle = tb_event_init(); + tb_assert_and_check_break(thread_event->handle); + + xm_lua_pushpointer(lua, (tb_pointer_t)thread_event); + ok = tb_true; + + } while (0); + + if (!ok) + { + if (thread_event) + { + if (thread_event->handle) + { + tb_event_exit(thread_event->handle); + thread_event->handle = tb_null; + } + tb_free(thread_event); + } + lua_pushnil(lua); + } + return 1; +} diff --git a/core/src/xmake/thread/event_post.c b/core/src/xmake/thread/event_post.c new file mode 100644 index 000000000..0b8e5dabd --- /dev/null +++ b/core/src/xmake/thread/event_post.c @@ -0,0 +1,46 @@ +/*!A cross-platform build utility based on Lua + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright (C) 2015-present, Xmake Open Source Community. + * + * @author ruki + * @file thread_event_lock.c + * + */ + +/* ////////////////////////////////////////////////////////////////////////////////////// + * trace + */ +#define TB_TRACE_MODULE_NAME "thread_event" +#define TB_TRACE_MODULE_DEBUG (0) + +/* ////////////////////////////////////////////////////////////////////////////////////// + * includes + */ +#include "prefix.h" + +/* ////////////////////////////////////////////////////////////////////////////////////// + * implementation + */ +tb_int_t xm_thread_event_post(lua_State* lua) +{ + tb_assert_and_check_return_val(lua, 0); + + xm_thread_event_t* thread_event = xm_thread_event_get(lua, 1); + tb_assert_and_check_return_val(thread_event && thread_event->handle, 0); + + lua_pushboolean(lua, tb_event_post(thread_event->handle)); + return 1; +} + diff --git a/core/src/xmake/thread/event_wait.c b/core/src/xmake/thread/event_wait.c new file mode 100644 index 000000000..0831036c6 --- /dev/null +++ b/core/src/xmake/thread/event_wait.c @@ -0,0 +1,47 @@ +/*!A cross-platform build utility based on Lua + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright (C) 2015-present, Xmake Open Source Community. + * + * @author ruki + * @file thread_event_unlock.c + * + */ + +/* ////////////////////////////////////////////////////////////////////////////////////// + * trace + */ +#define TB_TRACE_MODULE_NAME "thread_event" +#define TB_TRACE_MODULE_DEBUG (0) + +/* ////////////////////////////////////////////////////////////////////////////////////// + * includes + */ +#include "prefix.h" + +/* ////////////////////////////////////////////////////////////////////////////////////// + * implementation + */ +tb_int_t xm_thread_event_wait(lua_State* lua) +{ + tb_assert_and_check_return_val(lua, 0); + + xm_thread_event_t* thread_event = xm_thread_event_get(lua, 1); + tb_assert_and_check_return_val(thread_event && thread_event->handle, 0); + + tb_long_t timeout = (tb_long_t)luaL_checknumber(lua, 2); + lua_pushinteger(lua, tb_event_wait(thread_event->handle, timeout)); + return 1; +} + diff --git a/core/src/xmake/thread/mutex_exit.c b/core/src/xmake/thread/mutex_exit.c new file mode 100644 index 000000000..39d69ab8a --- /dev/null +++ b/core/src/xmake/thread/mutex_exit.c @@ -0,0 +1,55 @@ +/*!A cross-platform build utility based on Lua + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright (C) 2015-present, Xmake Open Source Community. + * + * @author ruki + * @file thread_mutex_exit.c + * + */ + +/* ////////////////////////////////////////////////////////////////////////////////////// + * trace + */ +#define TB_TRACE_MODULE_NAME "thread_mutex" +#define TB_TRACE_MODULE_DEBUG (0) + +/* ////////////////////////////////////////////////////////////////////////////////////// + * includes + */ +#include "prefix.h" + +/* ////////////////////////////////////////////////////////////////////////////////////// + * implementation + */ +tb_int_t xm_thread_mutex_exit(lua_State* lua) +{ + tb_assert_and_check_return_val(lua, 0); + + xm_thread_mutex_t* thread_mutex = xm_thread_mutex_get(lua, 1); + tb_assert_and_check_return_val(thread_mutex && thread_mutex->handle, 0); + + if (tb_atomic_fetch_and_sub(&thread_mutex->refn, 1) == 1) + { + if (thread_mutex->handle) + { + tb_mutex_exit(thread_mutex->handle); + thread_mutex->handle = tb_null; + } + tb_free(thread_mutex); + } + lua_pushboolean(lua, tb_true); + return 1; +} + diff --git a/core/src/xmake/thread/mutex_incref.c b/core/src/xmake/thread/mutex_incref.c new file mode 100644 index 000000000..34a234757 --- /dev/null +++ b/core/src/xmake/thread/mutex_incref.c @@ -0,0 +1,46 @@ +/*!A cross-platform build utility based on Lua + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright (C) 2015-present, Xmake Open Source Community. + * + * @author ruki + * @file thread_mutex_incref.c + * + */ + +/* ////////////////////////////////////////////////////////////////////////////////////// + * trace + */ +#define TB_TRACE_MODULE_NAME "thread_mutex" +#define TB_TRACE_MODULE_DEBUG (0) + +/* ////////////////////////////////////////////////////////////////////////////////////// + * includes + */ +#include "prefix.h" + +/* ////////////////////////////////////////////////////////////////////////////////////// + * implementation + */ +tb_int_t xm_thread_mutex_incref(lua_State* lua) +{ + tb_assert_and_check_return_val(lua, 0); + + xm_thread_mutex_t* thread_mutex = xm_thread_mutex_get(lua, 1); + tb_assert_and_check_return_val(thread_mutex && thread_mutex->handle, 0); + + lua_pushboolean(lua, tb_atomic_fetch_and_add(&thread_mutex->refn, 1) >= 1); + return 1; +} + diff --git a/core/src/xmake/thread/mutex_init.c b/core/src/xmake/thread/mutex_init.c new file mode 100644 index 000000000..ff69e82ad --- /dev/null +++ b/core/src/xmake/thread/mutex_init.c @@ -0,0 +1,70 @@ +/*!A cross-platform build utility based on Lua + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright (C) 2015-present, Xmake Open Source Community. + * + * @author ruki + * @file mutex_init.c + * + */ + +/* ////////////////////////////////////////////////////////////////////////////////////// + * trace + */ +#define TB_TRACE_MODULE_NAME "thread_mutex" +#define TB_TRACE_MODULE_DEBUG (0) + +/* ////////////////////////////////////////////////////////////////////////////////////// + * includes + */ +#include "prefix.h" + +/* ////////////////////////////////////////////////////////////////////////////////////// + * implementation + */ +tb_int_t xm_thread_mutex_init(lua_State* lua) +{ + tb_assert_and_check_return_val(lua, 0); + + tb_bool_t ok = tb_false; + xm_thread_mutex_t* thread_mutex = tb_null; + do + { + thread_mutex = tb_malloc0_type(xm_thread_mutex_t); + tb_assert_and_check_break(thread_mutex); + + thread_mutex->refn = 1; + thread_mutex->handle = tb_mutex_init(); + tb_assert_and_check_break(thread_mutex->handle); + + xm_lua_pushpointer(lua, (tb_pointer_t)thread_mutex); + ok = tb_true; + + } while (0); + + if (!ok) + { + if (thread_mutex) + { + if (thread_mutex->handle) + { + tb_mutex_exit(thread_mutex->handle); + thread_mutex->handle = tb_null; + } + tb_free(thread_mutex); + } + lua_pushnil(lua); + } + return 1; +} diff --git a/core/src/xmake/thread/mutex_lock.c b/core/src/xmake/thread/mutex_lock.c new file mode 100644 index 000000000..380301da1 --- /dev/null +++ b/core/src/xmake/thread/mutex_lock.c @@ -0,0 +1,46 @@ +/*!A cross-platform build utility based on Lua + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright (C) 2015-present, Xmake Open Source Community. + * + * @author ruki + * @file thread_mutex_lock.c + * + */ + +/* ////////////////////////////////////////////////////////////////////////////////////// + * trace + */ +#define TB_TRACE_MODULE_NAME "thread_mutex" +#define TB_TRACE_MODULE_DEBUG (0) + +/* ////////////////////////////////////////////////////////////////////////////////////// + * includes + */ +#include "prefix.h" + +/* ////////////////////////////////////////////////////////////////////////////////////// + * implementation + */ +tb_int_t xm_thread_mutex_lock(lua_State* lua) +{ + tb_assert_and_check_return_val(lua, 0); + + xm_thread_mutex_t* thread_mutex = xm_thread_mutex_get(lua, 1); + tb_assert_and_check_return_val(thread_mutex && thread_mutex->handle, 0); + + lua_pushboolean(lua, tb_mutex_enter(thread_mutex->handle)); + return 1; +} + diff --git a/core/src/xmake/thread/mutex_trylock.c b/core/src/xmake/thread/mutex_trylock.c new file mode 100644 index 000000000..7b83f3a90 --- /dev/null +++ b/core/src/xmake/thread/mutex_trylock.c @@ -0,0 +1,46 @@ +/*!A cross-platform build utility based on Lua + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright (C) 2015-present, Xmake Open Source Community. + * + * @author ruki + * @file thread_mutex_trylock.c + * + */ + +/* ////////////////////////////////////////////////////////////////////////////////////// + * trace + */ +#define TB_TRACE_MODULE_NAME "thread_mutex" +#define TB_TRACE_MODULE_DEBUG (0) + +/* ////////////////////////////////////////////////////////////////////////////////////// + * includes + */ +#include "prefix.h" + +/* ////////////////////////////////////////////////////////////////////////////////////// + * implementation + */ +tb_int_t xm_thread_mutex_trylock(lua_State* lua) +{ + tb_assert_and_check_return_val(lua, 0); + + xm_thread_mutex_t* thread_mutex = xm_thread_mutex_get(lua, 1); + tb_assert_and_check_return_val(thread_mutex && thread_mutex->handle, 0); + + lua_pushboolean(lua, tb_mutex_enter_try(thread_mutex->handle)); + return 1; +} + diff --git a/core/src/xmake/thread/mutex_unlock.c b/core/src/xmake/thread/mutex_unlock.c new file mode 100644 index 000000000..beb0c9e0a --- /dev/null +++ b/core/src/xmake/thread/mutex_unlock.c @@ -0,0 +1,46 @@ +/*!A cross-platform build utility based on Lua + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright (C) 2015-present, Xmake Open Source Community. + * + * @author ruki + * @file thread_mutex_unlock.c + * + */ + +/* ////////////////////////////////////////////////////////////////////////////////////// + * trace + */ +#define TB_TRACE_MODULE_NAME "thread_mutex" +#define TB_TRACE_MODULE_DEBUG (0) + +/* ////////////////////////////////////////////////////////////////////////////////////// + * includes + */ +#include "prefix.h" + +/* ////////////////////////////////////////////////////////////////////////////////////// + * implementation + */ +tb_int_t xm_thread_mutex_unlock(lua_State* lua) +{ + tb_assert_and_check_return_val(lua, 0); + + xm_thread_mutex_t* thread_mutex = xm_thread_mutex_get(lua, 1); + tb_assert_and_check_return_val(thread_mutex && thread_mutex->handle, 0); + + lua_pushboolean(lua, tb_mutex_leave(thread_mutex->handle)); + return 1; +} + diff --git a/core/src/xmake/thread/prefix.h b/core/src/xmake/thread/prefix.h new file mode 100644 index 000000000..2b841e6a7 --- /dev/null +++ b/core/src/xmake/thread/prefix.h @@ -0,0 +1,156 @@ +/*!A cross-platform build utility based on Lua + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright (C) 2015-present, Xmake Open Source Community. + * + * @author ruki + * @file prefix.h + * + */ +#ifndef XM_THREAD_PREFIX_H +#define XM_THREAD_PREFIX_H + +/* ////////////////////////////////////////////////////////////////////////////////////// + * includes + */ +#include "../prefix.h" + +/* ////////////////////////////////////////////////////////////////////////////////////// + * types + */ + +// the thread type +typedef struct __xm_thread_t +{ + tb_thread_ref_t handle; + tb_string_t callback; + tb_string_t callinfo; + +}xm_thread_t; + +// the thread value kind +typedef enum __xm_thread_value_kind_e +{ + XM_THREAD_VALUE_NIL = 0, + XM_THREAD_VALUE_BOOL = 1, + XM_THREAD_VALUE_INT = 2, + XM_THREAD_VALUE_NUM = 3, + XM_THREAD_VALUE_STR = 4 + +}xm_thread_value_kind_e; + +// the thread value type +typedef struct __xm_thread_value_t +{ + tb_uint32_t kind : 3; + tb_uint32_t size : 29; + union + { + tb_char_t* string; + tb_bool_t boolean; + lua_Integer integer; + lua_Number number; + } u; + +}xm_thread_value_t; + +// the thread event type +typedef struct __xm_thread_event_t +{ + tb_event_ref_t handle; + tb_atomic_t refn; + +}xm_thread_event_t; + +// the thread mutex type +typedef struct __xm_thread_mutex_t +{ + tb_mutex_ref_t handle; + tb_atomic_t refn; + +}xm_thread_mutex_t; + +// the thread semaphore type +typedef struct __xm_thread_semaphore_t +{ + tb_semaphore_ref_t handle; + tb_atomic_t refn; + +}xm_thread_semaphore_t; + +// the thread queue type +typedef struct __xm_thread_queue_t +{ + tb_queue_ref_t handle; + tb_atomic_t refn; + +}xm_thread_queue_t; + +// the thread sharedata type +typedef struct __xm_thread_sharedata_t +{ + xm_thread_value_t value; + tb_buffer_t buffer; + tb_atomic_t refn; + +}xm_thread_sharedata_t; + +// get the thread event from arguments +static __tb_inline__ xm_thread_event_t* xm_thread_event_get(lua_State* lua, tb_int_t index) +{ + xm_thread_event_t* thread_event = tb_null; + if (xm_lua_isinteger(lua, index)) thread_event = (xm_thread_event_t*)(tb_size_t)(tb_long_t)lua_tointeger(lua, index); + else if (xm_lua_ispointer(lua, index)) thread_event = (xm_thread_event_t*)xm_lua_topointer(lua, index); + return thread_event; +} + +// get the thread mutex from arguments +static __tb_inline__ xm_thread_mutex_t* xm_thread_mutex_get(lua_State* lua, tb_int_t index) +{ + xm_thread_mutex_t* thread_mutex = tb_null; + if (xm_lua_isinteger(lua, index)) thread_mutex = (xm_thread_mutex_t*)(tb_size_t)(tb_long_t)lua_tointeger(lua, index); + else if (xm_lua_ispointer(lua, index)) thread_mutex = (xm_thread_mutex_t*)xm_lua_topointer(lua, index); + return thread_mutex; +} + +// get the thread semaphore from arguments +static __tb_inline__ xm_thread_semaphore_t* xm_thread_semaphore_get(lua_State* lua, tb_int_t index) +{ + xm_thread_semaphore_t* thread_semaphore = tb_null; + if (xm_lua_isinteger(lua, index)) thread_semaphore = (xm_thread_semaphore_t*)(tb_size_t)(tb_long_t)lua_tointeger(lua, index); + else if (xm_lua_ispointer(lua, index)) thread_semaphore = (xm_thread_semaphore_t*)xm_lua_topointer(lua, index); + return thread_semaphore; +} + +// get the thread queue from arguments +static __tb_inline__ xm_thread_queue_t* xm_thread_queue_get(lua_State* lua, tb_int_t index) +{ + xm_thread_queue_t* thread_queue = tb_null; + if (xm_lua_isinteger(lua, index)) thread_queue = (xm_thread_queue_t*)(tb_size_t)(tb_long_t)lua_tointeger(lua, index); + else if (xm_lua_ispointer(lua, index)) thread_queue = (xm_thread_queue_t*)xm_lua_topointer(lua, index); + return thread_queue; +} + +// get the thread sharedata from arguments +static __tb_inline__ xm_thread_sharedata_t* xm_thread_sharedata_get(lua_State* lua, tb_int_t index) +{ + xm_thread_sharedata_t* thread_sharedata = tb_null; + if (xm_lua_isinteger(lua, index)) thread_sharedata = (xm_thread_sharedata_t*)(tb_size_t)(tb_long_t)lua_tointeger(lua, index); + else if (xm_lua_ispointer(lua, index)) thread_sharedata = (xm_thread_sharedata_t*)xm_lua_topointer(lua, index); + return thread_sharedata; +} + +#endif + + diff --git a/core/src/xmake/thread/queue_clear.c b/core/src/xmake/thread/queue_clear.c new file mode 100644 index 000000000..4888babe2 --- /dev/null +++ b/core/src/xmake/thread/queue_clear.c @@ -0,0 +1,47 @@ +/*!A cross-platform build utility based on Lua + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright (C) 2015-present, Xmake Open Source Community. + * + * @author ruki + * @file thread_queue_clear.c + * + */ + +/* ////////////////////////////////////////////////////////////////////////////////////// + * trace + */ +#define TB_TRACE_MODULE_NAME "thread_queue" +#define TB_TRACE_MODULE_DEBUG (0) + +/* ////////////////////////////////////////////////////////////////////////////////////// + * includes + */ +#include "prefix.h" + +/* ////////////////////////////////////////////////////////////////////////////////////// + * implementation + */ +tb_int_t xm_thread_queue_clear(lua_State* lua) +{ + tb_assert_and_check_return_val(lua, 0); + + xm_thread_queue_t* thread_queue = xm_thread_queue_get(lua, 1); + tb_assert_and_check_return_val(thread_queue && thread_queue->handle, 0); + + tb_queue_clear(thread_queue->handle); + lua_pushboolean(lua, tb_true); + return 1; +} + diff --git a/core/src/xmake/thread/queue_exit.c b/core/src/xmake/thread/queue_exit.c new file mode 100644 index 000000000..8178ea22f --- /dev/null +++ b/core/src/xmake/thread/queue_exit.c @@ -0,0 +1,55 @@ +/*!A cross-platform build utility based on Lua + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright (C) 2015-present, Xmake Open Source Community. + * + * @author ruki + * @file thread_queue_exit.c + * + */ + +/* ////////////////////////////////////////////////////////////////////////////////////// + * trace + */ +#define TB_TRACE_MODULE_NAME "thread_queue" +#define TB_TRACE_MODULE_DEBUG (0) + +/* ////////////////////////////////////////////////////////////////////////////////////// + * includes + */ +#include "prefix.h" + +/* ////////////////////////////////////////////////////////////////////////////////////// + * implementation + */ +tb_int_t xm_thread_queue_exit(lua_State* lua) +{ + tb_assert_and_check_return_val(lua, 0); + + xm_thread_queue_t* thread_queue = xm_thread_queue_get(lua, 1); + tb_assert_and_check_return_val(thread_queue && thread_queue->handle, 0); + + if (tb_atomic_fetch_and_sub(&thread_queue->refn, 1) == 1) + { + if (thread_queue->handle) + { + tb_queue_exit(thread_queue->handle); + thread_queue->handle = tb_null; + } + tb_free(thread_queue); + } + lua_pushboolean(lua, tb_true); + return 1; +} + diff --git a/core/src/xmake/thread/queue_incref.c b/core/src/xmake/thread/queue_incref.c new file mode 100644 index 000000000..4f06807c4 --- /dev/null +++ b/core/src/xmake/thread/queue_incref.c @@ -0,0 +1,46 @@ +/*!A cross-platform build utility based on Lua + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright (C) 2015-present, Xmake Open Source Community. + * + * @author ruki + * @file thread_queue_incref.c + * + */ + +/* ////////////////////////////////////////////////////////////////////////////////////// + * trace + */ +#define TB_TRACE_MODULE_NAME "thread_queue" +#define TB_TRACE_MODULE_DEBUG (0) + +/* ////////////////////////////////////////////////////////////////////////////////////// + * includes + */ +#include "prefix.h" + +/* ////////////////////////////////////////////////////////////////////////////////////// + * implementation + */ +tb_int_t xm_thread_queue_incref(lua_State* lua) +{ + tb_assert_and_check_return_val(lua, 0); + + xm_thread_queue_t* thread_queue = xm_thread_queue_get(lua, 1); + tb_assert_and_check_return_val(thread_queue && thread_queue->handle, 0); + + lua_pushboolean(lua, tb_atomic_fetch_and_add(&thread_queue->refn, 1) >= 1); + return 1; +} + diff --git a/core/src/xmake/thread/queue_init.c b/core/src/xmake/thread/queue_init.c new file mode 100644 index 000000000..0c8af884d --- /dev/null +++ b/core/src/xmake/thread/queue_init.c @@ -0,0 +1,87 @@ +/*!A cross-platform build utility based on Lua + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright (C) 2015-present, Xmake Open Source Community. + * + * @author ruki + * @file queue_init.c + * + */ + +/* ////////////////////////////////////////////////////////////////////////////////////// + * trace + */ +#define TB_TRACE_MODULE_NAME "thread_queue" +#define TB_TRACE_MODULE_DEBUG (0) + +/* ////////////////////////////////////////////////////////////////////////////////////// + * includes + */ +#include "prefix.h" + +/* ////////////////////////////////////////////////////////////////////////////////////// + * private implementation + */ +static tb_void_t xm_thread_value_free(tb_element_ref_t element, tb_pointer_t buff) +{ + xm_thread_value_t* item = (xm_thread_value_t*)buff; + if (item) + { + if (item->kind == XM_THREAD_VALUE_STR) + { + if (item->u.string) tb_free((tb_pointer_t)item->u.string); + item->u.string = tb_null; + } + item->size = 0; + } +} + +/* ////////////////////////////////////////////////////////////////////////////////////// + * implementation + */ +tb_int_t xm_thread_queue_init(lua_State* lua) +{ + tb_assert_and_check_return_val(lua, 0); + + tb_bool_t ok = tb_false; + xm_thread_queue_t* thread_queue = tb_null; + do + { + thread_queue = tb_malloc0_type(xm_thread_queue_t); + tb_assert_and_check_break(thread_queue); + + thread_queue->refn = 1; + thread_queue->handle = tb_queue_init(0, tb_element_mem(sizeof(xm_thread_value_t), xm_thread_value_free, tb_null)); + tb_assert_and_check_break(thread_queue->handle); + + xm_lua_pushpointer(lua, (tb_pointer_t)thread_queue); + ok = tb_true; + + } while (0); + + if (!ok) + { + if (thread_queue) + { + if (thread_queue->handle) + { + tb_queue_exit(thread_queue->handle); + thread_queue->handle = tb_null; + } + tb_free(thread_queue); + } + lua_pushnil(lua); + } + return 1; +} diff --git a/core/src/xmake/thread/queue_pop.c b/core/src/xmake/thread/queue_pop.c new file mode 100644 index 000000000..c666a85dd --- /dev/null +++ b/core/src/xmake/thread/queue_pop.c @@ -0,0 +1,92 @@ +/*!A cross-platform build utility based on Lua + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright (C) 2015-present, Xmake Open Source Community. + * + * @author ruki + * @file thread_queue_pop.c + * + */ + +/* ////////////////////////////////////////////////////////////////////////////////////// + * trace + */ +#define TB_TRACE_MODULE_NAME "thread_queue" +#define TB_TRACE_MODULE_DEBUG (0) + +/* ////////////////////////////////////////////////////////////////////////////////////// + * includes + */ +#include "prefix.h" + +/* ////////////////////////////////////////////////////////////////////////////////////// + * implementation + */ +tb_int_t xm_thread_queue_pop(lua_State* lua) +{ + tb_assert_and_check_return_val(lua, 0); + + xm_thread_queue_t* thread_queue = xm_thread_queue_get(lua, 1); + tb_assert_and_check_return_val(thread_queue && thread_queue->handle, 0); + + if (tb_queue_null(thread_queue->handle)) + { + lua_pushnil(lua); + lua_pushliteral(lua, "the thread queue is empty"); + return 2; + } + + xm_thread_value_t* item = (xm_thread_value_t*)tb_queue_get(thread_queue->handle); + tb_assert_and_check_return_val(item, 0); + + tb_bool_t ok = tb_false; + switch (item->kind) + { + case XM_THREAD_VALUE_STR: + if (item->size) + lua_pushlstring(lua, item->u.string, item->size); + else lua_pushliteral(lua, ""); + ok = tb_true; + break; + case XM_THREAD_VALUE_INT: + lua_pushinteger(lua, item->u.integer); + ok = tb_true; + break; + case XM_THREAD_VALUE_NUM: + lua_pushnumber(lua, item->u.number); + ok = tb_true; + break; + case XM_THREAD_VALUE_BOOL: + lua_pushboolean(lua, item->u.boolean); + ok = tb_true; + break; + case XM_THREAD_VALUE_NIL: + lua_pushnil(lua); + ok = tb_true; + break; + default: + break; + } + + if (!ok) + { + lua_pushnil(lua); + lua_pushliteral(lua, "invalid thread queue item"); + return 2; + } + + tb_queue_pop(thread_queue->handle); + return 1; +} + diff --git a/core/src/xmake/thread/queue_push.c b/core/src/xmake/thread/queue_push.c new file mode 100644 index 000000000..8125f2b9a --- /dev/null +++ b/core/src/xmake/thread/queue_push.c @@ -0,0 +1,96 @@ +/*!A cross-platform build utility based on Lua + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright (C) 2015-present, Xmake Open Source Community. + * + * @author ruki + * @file thread_queue_push.c + * + */ + +/* ////////////////////////////////////////////////////////////////////////////////////// + * trace + */ +#define TB_TRACE_MODULE_NAME "thread_queue" +#define TB_TRACE_MODULE_DEBUG (0) + +/* ////////////////////////////////////////////////////////////////////////////////////// + * includes + */ +#include "prefix.h" + +/* ////////////////////////////////////////////////////////////////////////////////////// + * implementation + */ +tb_int_t xm_thread_queue_push(lua_State* lua) +{ + tb_assert_and_check_return_val(lua, 0); + + xm_thread_queue_t* thread_queue = xm_thread_queue_get(lua, 1); + tb_assert_and_check_return_val(thread_queue && thread_queue->handle, 0); + + if (tb_queue_full(thread_queue->handle)) + { + lua_pushboolean(lua, tb_false); + lua_pushliteral(lua, "the thread queue is full"); + return 2; + } + + xm_thread_value_t item; + if (lua_isstring(lua, 2)) + { + size_t data_size = 0; + tb_char_t const* data = luaL_checklstring(lua, 2, &data_size); + tb_assert_and_check_return_val(data, 0); + + item.kind = (tb_uint32_t)XM_THREAD_VALUE_STR; + item.size = (tb_uint32_t)data_size; + if (data_size) + { + item.u.string = tb_malloc_cstr(data_size); + tb_assert_and_check_return_val(item.u.string, 0); + tb_memcpy(item.u.string, data, data_size); + } + } + else if (xm_lua_isinteger(lua, 2)) + { + item.kind = (tb_uint32_t)XM_THREAD_VALUE_INT; + item.u.integer = lua_tointeger(lua, 2); + } + else if (lua_isnumber(lua, 2)) + { + item.kind = (tb_uint32_t)XM_THREAD_VALUE_NUM; + item.u.number = lua_tonumber(lua, 2); + } + else if (lua_isboolean(lua, 2)) + { + item.kind = (tb_uint32_t)XM_THREAD_VALUE_BOOL; + item.u.boolean = lua_toboolean(lua, 2); + } + else if (lua_isnil(lua, 2)) + { + item.kind = (tb_uint32_t)XM_THREAD_VALUE_NIL; + } + else + { + lua_pushboolean(lua, tb_false); + lua_pushliteral(lua, "unsupported thread queue item"); + return 2; + } + + tb_queue_put(thread_queue->handle, &item); + lua_pushboolean(lua, tb_true); + return 1; +} + diff --git a/core/src/xmake/thread/queue_size.c b/core/src/xmake/thread/queue_size.c new file mode 100644 index 000000000..559a1dceb --- /dev/null +++ b/core/src/xmake/thread/queue_size.c @@ -0,0 +1,46 @@ +/*!A cross-platform build utility based on Lua + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright (C) 2015-present, Xmake Open Source Community. + * + * @author ruki + * @file thread_queue_lock.c + * + */ + +/* ////////////////////////////////////////////////////////////////////////////////////// + * trace + */ +#define TB_TRACE_MODULE_NAME "thread_queue" +#define TB_TRACE_MODULE_DEBUG (0) + +/* ////////////////////////////////////////////////////////////////////////////////////// + * includes + */ +#include "prefix.h" + +/* ////////////////////////////////////////////////////////////////////////////////////// + * implementation + */ +tb_int_t xm_thread_queue_size(lua_State* lua) +{ + tb_assert_and_check_return_val(lua, 0); + + xm_thread_queue_t* thread_queue = xm_thread_queue_get(lua, 1); + tb_assert_and_check_return_val(thread_queue && thread_queue->handle, 0); + + lua_pushinteger(lua, (tb_int_t)tb_queue_size(thread_queue->handle)); + return 1; +} + diff --git a/core/src/xmake/thread/semaphore_exit.c b/core/src/xmake/thread/semaphore_exit.c new file mode 100644 index 000000000..cffffa249 --- /dev/null +++ b/core/src/xmake/thread/semaphore_exit.c @@ -0,0 +1,55 @@ +/*!A cross-platform build utility based on Lua + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright (C) 2015-present, Xmake Open Source Community. + * + * @author ruki + * @file thread_semaphore_exit.c + * + */ + +/* ////////////////////////////////////////////////////////////////////////////////////// + * trace + */ +#define TB_TRACE_MODULE_NAME "thread_semaphore" +#define TB_TRACE_MODULE_DEBUG (0) + +/* ////////////////////////////////////////////////////////////////////////////////////// + * includes + */ +#include "prefix.h" + +/* ////////////////////////////////////////////////////////////////////////////////////// + * implementation + */ +tb_int_t xm_thread_semaphore_exit(lua_State* lua) +{ + tb_assert_and_check_return_val(lua, 0); + + xm_thread_semaphore_t* thread_semaphore = xm_thread_semaphore_get(lua, 1); + tb_assert_and_check_return_val(thread_semaphore && thread_semaphore->handle, 0); + + if (tb_atomic_fetch_and_sub(&thread_semaphore->refn, 1) == 1) + { + if (thread_semaphore->handle) + { + tb_semaphore_exit(thread_semaphore->handle); + thread_semaphore->handle = tb_null; + } + tb_free(thread_semaphore); + } + lua_pushboolean(lua, tb_true); + return 1; +} + diff --git a/core/src/xmake/thread/semaphore_incref.c b/core/src/xmake/thread/semaphore_incref.c new file mode 100644 index 000000000..84c2118d3 --- /dev/null +++ b/core/src/xmake/thread/semaphore_incref.c @@ -0,0 +1,46 @@ +/*!A cross-platform build utility based on Lua + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright (C) 2015-present, Xmake Open Source Community. + * + * @author ruki + * @file thread_semaphore_incref.c + * + */ + +/* ////////////////////////////////////////////////////////////////////////////////////// + * trace + */ +#define TB_TRACE_MODULE_NAME "thread_semaphore" +#define TB_TRACE_MODULE_DEBUG (0) + +/* ////////////////////////////////////////////////////////////////////////////////////// + * includes + */ +#include "prefix.h" + +/* ////////////////////////////////////////////////////////////////////////////////////// + * implementation + */ +tb_int_t xm_thread_semaphore_incref(lua_State* lua) +{ + tb_assert_and_check_return_val(lua, 0); + + xm_thread_semaphore_t* thread_semaphore = xm_thread_semaphore_get(lua, 1); + tb_assert_and_check_return_val(thread_semaphore && thread_semaphore->handle, 0); + + lua_pushboolean(lua, tb_atomic_fetch_and_add(&thread_semaphore->refn, 1) >= 1); + return 1; +} + diff --git a/core/src/xmake/thread/semaphore_init.c b/core/src/xmake/thread/semaphore_init.c new file mode 100644 index 000000000..976b48de9 --- /dev/null +++ b/core/src/xmake/thread/semaphore_init.c @@ -0,0 +1,72 @@ +/*!A cross-platform build utility based on Lua + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright (C) 2015-present, Xmake Open Source Community. + * + * @author ruki + * @file semaphore_init.c + * + */ + +/* ////////////////////////////////////////////////////////////////////////////////////// + * trace + */ +#define TB_TRACE_MODULE_NAME "thread_semaphore" +#define TB_TRACE_MODULE_DEBUG (0) + +/* ////////////////////////////////////////////////////////////////////////////////////// + * includes + */ +#include "prefix.h" + +/* ////////////////////////////////////////////////////////////////////////////////////// + * implementation + */ +tb_int_t xm_thread_semaphore_init(lua_State* lua) +{ + tb_assert_and_check_return_val(lua, 0); + + tb_bool_t ok = tb_false; + xm_thread_semaphore_t* thread_semaphore = tb_null; + do + { + tb_long_t value = (tb_long_t)luaL_checknumber(lua, 1); + + thread_semaphore = tb_malloc0_type(xm_thread_semaphore_t); + tb_assert_and_check_break(thread_semaphore); + + thread_semaphore->refn = 1; + thread_semaphore->handle = tb_semaphore_init(value); + tb_assert_and_check_break(thread_semaphore->handle); + + xm_lua_pushpointer(lua, (tb_pointer_t)thread_semaphore); + ok = tb_true; + + } while (0); + + if (!ok) + { + if (thread_semaphore) + { + if (thread_semaphore->handle) + { + tb_semaphore_exit(thread_semaphore->handle); + thread_semaphore->handle = tb_null; + } + tb_free(thread_semaphore); + } + lua_pushnil(lua); + } + return 1; +} diff --git a/core/src/xmake/thread/semaphore_post.c b/core/src/xmake/thread/semaphore_post.c new file mode 100644 index 000000000..9ca94bda5 --- /dev/null +++ b/core/src/xmake/thread/semaphore_post.c @@ -0,0 +1,47 @@ +/*!A cross-platform build utility based on Lua + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright (C) 2015-present, Xmake Open Source Community. + * + * @author ruki + * @file thread_semaphore_lock.c + * + */ + +/* ////////////////////////////////////////////////////////////////////////////////////// + * trace + */ +#define TB_TRACE_MODULE_NAME "thread_semaphore" +#define TB_TRACE_MODULE_DEBUG (0) + +/* ////////////////////////////////////////////////////////////////////////////////////// + * includes + */ +#include "prefix.h" + +/* ////////////////////////////////////////////////////////////////////////////////////// + * implementation + */ +tb_int_t xm_thread_semaphore_post(lua_State* lua) +{ + tb_assert_and_check_return_val(lua, 0); + + xm_thread_semaphore_t* thread_semaphore = xm_thread_semaphore_get(lua, 1); + tb_assert_and_check_return_val(thread_semaphore && thread_semaphore->handle, 0); + + tb_long_t value = (tb_long_t)luaL_checknumber(lua, 2); + lua_pushboolean(lua, tb_semaphore_post(thread_semaphore->handle, value)); + return 1; +} + diff --git a/core/src/xmake/thread/semaphore_wait.c b/core/src/xmake/thread/semaphore_wait.c new file mode 100644 index 000000000..c8e4d1491 --- /dev/null +++ b/core/src/xmake/thread/semaphore_wait.c @@ -0,0 +1,47 @@ +/*!A cross-platform build utility based on Lua + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright (C) 2015-present, Xmake Open Source Community. + * + * @author ruki + * @file thread_semaphore_unlock.c + * + */ + +/* ////////////////////////////////////////////////////////////////////////////////////// + * trace + */ +#define TB_TRACE_MODULE_NAME "thread_semaphore" +#define TB_TRACE_MODULE_DEBUG (0) + +/* ////////////////////////////////////////////////////////////////////////////////////// + * includes + */ +#include "prefix.h" + +/* ////////////////////////////////////////////////////////////////////////////////////// + * implementation + */ +tb_int_t xm_thread_semaphore_wait(lua_State* lua) +{ + tb_assert_and_check_return_val(lua, 0); + + xm_thread_semaphore_t* thread_semaphore = xm_thread_semaphore_get(lua, 1); + tb_assert_and_check_return_val(thread_semaphore && thread_semaphore->handle, 0); + + tb_long_t timeout = (tb_long_t)luaL_checknumber(lua, 2); + lua_pushinteger(lua, tb_semaphore_wait(thread_semaphore->handle, timeout)); + return 1; +} + diff --git a/core/src/xmake/thread/sharedata_clear.c b/core/src/xmake/thread/sharedata_clear.c new file mode 100644 index 000000000..0c8b4afcf --- /dev/null +++ b/core/src/xmake/thread/sharedata_clear.c @@ -0,0 +1,48 @@ +/*!A cross-platform build utility based on Lua + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright (C) 2015-present, Xmake Open Source Community. + * + * @author ruki + * @file thread_sharedata_clear.c + * + */ + +/* ////////////////////////////////////////////////////////////////////////////////////// + * trace + */ +#define TB_TRACE_MODULE_NAME "thread_sharedata" +#define TB_TRACE_MODULE_DEBUG (0) + +/* ////////////////////////////////////////////////////////////////////////////////////// + * includes + */ +#include "prefix.h" + +/* ////////////////////////////////////////////////////////////////////////////////////// + * implementation + */ +tb_int_t xm_thread_sharedata_clear(lua_State* lua) +{ + tb_assert_and_check_return_val(lua, 0); + + xm_thread_sharedata_t* thread_sharedata = xm_thread_sharedata_get(lua, 1); + tb_assert_and_check_return_val(thread_sharedata, 0); + + thread_sharedata->value.kind = XM_THREAD_VALUE_NIL; + tb_buffer_clear(&thread_sharedata->buffer); + lua_pushboolean(lua, tb_true); + return 1; +} + diff --git a/core/src/xmake/thread/sharedata_exit.c b/core/src/xmake/thread/sharedata_exit.c new file mode 100644 index 000000000..ad4a9f33f --- /dev/null +++ b/core/src/xmake/thread/sharedata_exit.c @@ -0,0 +1,51 @@ +/*!A cross-platform build utility based on Lua + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright (C) 2015-present, Xmake Open Source Community. + * + * @author ruki + * @file thread_sharedata_exit.c + * + */ + +/* ////////////////////////////////////////////////////////////////////////////////////// + * trace + */ +#define TB_TRACE_MODULE_NAME "thread_sharedata" +#define TB_TRACE_MODULE_DEBUG (0) + +/* ////////////////////////////////////////////////////////////////////////////////////// + * includes + */ +#include "prefix.h" + +/* ////////////////////////////////////////////////////////////////////////////////////// + * implementation + */ +tb_int_t xm_thread_sharedata_exit(lua_State* lua) +{ + tb_assert_and_check_return_val(lua, 0); + + xm_thread_sharedata_t* thread_sharedata = xm_thread_sharedata_get(lua, 1); + tb_assert_and_check_return_val(thread_sharedata, 0); + + if (tb_atomic_fetch_and_sub(&thread_sharedata->refn, 1) == 1) + { + tb_buffer_exit(&thread_sharedata->buffer); + tb_free(thread_sharedata); + } + lua_pushboolean(lua, tb_true); + return 1; +} + diff --git a/core/src/xmake/thread/sharedata_get.c b/core/src/xmake/thread/sharedata_get.c new file mode 100644 index 000000000..abd020d3b --- /dev/null +++ b/core/src/xmake/thread/sharedata_get.c @@ -0,0 +1,82 @@ +/*!A cross-platform build utility based on Lua + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright (C) 2015-present, Xmake Open Source Community. + * + * @author ruki + * @file thread_sharedata_get.c + * + */ + +/* ////////////////////////////////////////////////////////////////////////////////////// + * trace + */ +#define TB_TRACE_MODULE_NAME "thread_sharedata" +#define TB_TRACE_MODULE_DEBUG (0) + +/* ////////////////////////////////////////////////////////////////////////////////////// + * includes + */ +#include "prefix.h" + +/* ////////////////////////////////////////////////////////////////////////////////////// + * implementation + */ +tb_int_t xm_thread_sharedata_get_(lua_State* lua) +{ + tb_assert_and_check_return_val(lua, 0); + + xm_thread_sharedata_t* thread_sharedata = xm_thread_sharedata_get(lua, 1); + tb_assert_and_check_return_val(thread_sharedata, 0); + + tb_bool_t ok = tb_false; + switch (thread_sharedata->value.kind) + { + case XM_THREAD_VALUE_STR: + if (tb_buffer_size(&thread_sharedata->buffer) > 0) + lua_pushlstring(lua, (tb_char_t*)tb_buffer_data(&thread_sharedata->buffer), tb_buffer_size(&thread_sharedata->buffer)); + else lua_pushliteral(lua, ""); + ok = tb_true; + break; + case XM_THREAD_VALUE_INT: + lua_pushinteger(lua, thread_sharedata->value.u.integer); + ok = tb_true; + break; + case XM_THREAD_VALUE_NUM: + lua_pushnumber(lua, thread_sharedata->value.u.number); + ok = tb_true; + break; + case XM_THREAD_VALUE_BOOL: + lua_pushboolean(lua, thread_sharedata->value.u.boolean); + ok = tb_true; + break; + case XM_THREAD_VALUE_NIL: + lua_pushnil(lua); + ok = tb_true; + break; + default: + break; + } + + if (!ok) + { + lua_pushnil(lua); + lua_pushliteral(lua, "invalid thread sharedata thread_sharedata"); + return 2; + } + + return 1; +} + + diff --git a/core/src/xmake/thread/sharedata_incref.c b/core/src/xmake/thread/sharedata_incref.c new file mode 100644 index 000000000..e0d32c600 --- /dev/null +++ b/core/src/xmake/thread/sharedata_incref.c @@ -0,0 +1,46 @@ +/*!A cross-platform build utility based on Lua + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright (C) 2015-present, Xmake Open Source Community. + * + * @author ruki + * @file thread_sharedata_incref.c + * + */ + +/* ////////////////////////////////////////////////////////////////////////////////////// + * trace + */ +#define TB_TRACE_MODULE_NAME "thread_sharedata" +#define TB_TRACE_MODULE_DEBUG (0) + +/* ////////////////////////////////////////////////////////////////////////////////////// + * includes + */ +#include "prefix.h" + +/* ////////////////////////////////////////////////////////////////////////////////////// + * implementation + */ +tb_int_t xm_thread_sharedata_incref(lua_State* lua) +{ + tb_assert_and_check_return_val(lua, 0); + + xm_thread_sharedata_t* thread_sharedata = xm_thread_sharedata_get(lua, 1); + tb_assert_and_check_return_val(thread_sharedata, 0); + + lua_pushboolean(lua, tb_atomic_fetch_and_add(&thread_sharedata->refn, 1) >= 1); + return 1; +} + diff --git a/core/src/xmake/thread/sharedata_init.c b/core/src/xmake/thread/sharedata_init.c new file mode 100644 index 000000000..b38fc217a --- /dev/null +++ b/core/src/xmake/thread/sharedata_init.c @@ -0,0 +1,66 @@ +/*!A cross-platform build utility based on Lua + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright (C) 2015-present, Xmake Open Source Community. + * + * @author ruki + * @file sharedata_init.c + * + */ + +/* ////////////////////////////////////////////////////////////////////////////////////// + * trace + */ +#define TB_TRACE_MODULE_NAME "thread_sharedata" +#define TB_TRACE_MODULE_DEBUG (0) + +/* ////////////////////////////////////////////////////////////////////////////////////// + * includes + */ +#include "prefix.h" + +/* ////////////////////////////////////////////////////////////////////////////////////// + * implementation + */ +tb_int_t xm_thread_sharedata_init(lua_State* lua) +{ + tb_assert_and_check_return_val(lua, 0); + + tb_bool_t ok = tb_false; + xm_thread_sharedata_t* thread_sharedata = tb_null; + do + { + thread_sharedata = tb_malloc0_type(xm_thread_sharedata_t); + tb_assert_and_check_break(thread_sharedata); + + thread_sharedata->refn = 1; + thread_sharedata->value.kind = XM_THREAD_VALUE_NIL; + tb_buffer_init(&thread_sharedata->buffer); + + xm_lua_pushpointer(lua, (tb_pointer_t)thread_sharedata); + ok = tb_true; + + } while (0); + + if (!ok) + { + if (thread_sharedata) + { + tb_buffer_exit(&thread_sharedata->buffer); + tb_free(thread_sharedata); + } + lua_pushnil(lua); + } + return 1; +} diff --git a/core/src/xmake/thread/sharedata_set.c b/core/src/xmake/thread/sharedata_set.c new file mode 100644 index 000000000..08e661f20 --- /dev/null +++ b/core/src/xmake/thread/sharedata_set.c @@ -0,0 +1,84 @@ +/*!A cross-platform build utility based on Lua + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright (C) 2015-present, Xmake Open Source Community. + * + * @author ruki + * @file thread_sharedata_set.c + * + */ + +/* ////////////////////////////////////////////////////////////////////////////////////// + * trace + */ +#define TB_TRACE_MODULE_NAME "thread_sharedata" +#define TB_TRACE_MODULE_DEBUG (0) + +/* ////////////////////////////////////////////////////////////////////////////////////// + * includes + */ +#include "prefix.h" + +/* ////////////////////////////////////////////////////////////////////////////////////// + * implementation + */ +tb_int_t xm_thread_sharedata_set(lua_State* lua) +{ + tb_assert_and_check_return_val(lua, 0); + + xm_thread_sharedata_t* thread_sharedata = xm_thread_sharedata_get(lua, 1); + tb_assert_and_check_return_val(thread_sharedata, 0); + + if (lua_isstring(lua, 2)) + { + size_t data_size = 0; + tb_char_t const* data = luaL_checklstring(lua, 2, &data_size); + tb_assert_and_check_return_val(data, 0); + + thread_sharedata->value.kind = (tb_uint32_t)XM_THREAD_VALUE_STR; + if (data_size) + tb_buffer_memncpy(&thread_sharedata->buffer, (tb_byte_t const*)data, data_size); + else tb_buffer_clear(&thread_sharedata->buffer); + } + else if (xm_lua_isinteger(lua, 2)) + { + thread_sharedata->value.kind = (tb_uint32_t)XM_THREAD_VALUE_INT; + thread_sharedata->value.u.integer = lua_tointeger(lua, 2); + } + else if (lua_isnumber(lua, 2)) + { + thread_sharedata->value.kind = (tb_uint32_t)XM_THREAD_VALUE_NUM; + thread_sharedata->value.u.number = lua_tonumber(lua, 2); + } + else if (lua_isboolean(lua, 2)) + { + thread_sharedata->value.kind = (tb_uint32_t)XM_THREAD_VALUE_BOOL; + thread_sharedata->value.u.boolean = lua_toboolean(lua, 2); + } + else if (lua_isnil(lua, 2)) + { + thread_sharedata->value.kind = (tb_uint32_t)XM_THREAD_VALUE_NIL; + } + else + { + lua_pushboolean(lua, tb_false); + lua_pushliteral(lua, "unsupported thread sharedata item"); + return 2; + } + + lua_pushboolean(lua, tb_true); + return 1; +} + + diff --git a/core/src/xmake/thread/thread_exit.c b/core/src/xmake/thread/thread_exit.c new file mode 100644 index 000000000..9d2c8e908 --- /dev/null +++ b/core/src/xmake/thread/thread_exit.c @@ -0,0 +1,64 @@ +/*!A cross-platform build utility based on Lua + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright (C) 2015-present, Xmake Open Source Community. + * + * @author ruki + * @file thread_exit.c + * + */ + +/* ////////////////////////////////////////////////////////////////////////////////////// + * trace + */ +#define TB_TRACE_MODULE_NAME "thread" +#define TB_TRACE_MODULE_DEBUG (0) + +/* ////////////////////////////////////////////////////////////////////////////////////// + * includes + */ +#include "prefix.h" + +/* ////////////////////////////////////////////////////////////////////////////////////// + * implementation + */ +tb_int_t xm_thread_exit(lua_State* lua) +{ + // check + tb_assert_and_check_return_val(lua, 0); + + // is pointer? + if (!xm_lua_ispointer(lua, 1)) + return 0; + + // get thread + xm_thread_t* thread = (xm_thread_t*)xm_lua_topointer(lua, 1); + tb_check_return_val(thread, 0); + + // exit thread + if (thread) + { + tb_string_exit(&thread->callback); + tb_string_exit(&thread->callinfo); + if (thread->handle) + { + tb_thread_exit(thread->handle); + thread->handle = tb_null; + } + tb_free(thread); + } + lua_pushboolean(lua, tb_true); + return 1; +} + diff --git a/core/src/xmake/thread/thread_init.c b/core/src/xmake/thread/thread_init.c new file mode 100644 index 000000000..6fc44267a --- /dev/null +++ b/core/src/xmake/thread/thread_init.c @@ -0,0 +1,146 @@ +/*!A cross-platform build utility based on Lua + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright (C) 2015-present, Xmake Open Source Community. + * + * @author ruki + * @file thread_init.c + * + */ + +/* ////////////////////////////////////////////////////////////////////////////////////// + * trace + */ +#define TB_TRACE_MODULE_NAME "thread" +#define TB_TRACE_MODULE_DEBUG (0) + +/* ////////////////////////////////////////////////////////////////////////////////////// + * includes + */ +#include "prefix.h" +#include "../engine.h" +#include "../engine_pool.h" + +/* ////////////////////////////////////////////////////////////////////////////////////// + * macros + */ +#define XM_THREAD_ENGINE_NAME "xmake" + +/* ////////////////////////////////////////////////////////////////////////////////////// + * private implementation + */ + +static tb_int_t xm_thread_func(tb_cpointer_t priv) +{ + xm_thread_t* thread = (xm_thread_t*)priv; + tb_assert_and_check_return_val(thread, 0); + + xm_engine_ref_t engine = xm_engine_pool_alloc(xm_engine_pool()); + if (!engine) engine = xm_engine_init(XM_THREAD_ENGINE_NAME, tb_null); + if (engine) + { + lua_State* lua = xm_engine_lua(engine); + tb_assert(lua); + + // pass callback + tb_char_t const* callback_data = tb_string_cstr(&thread->callback); + tb_size_t callback_size = tb_string_size(&thread->callback); + if (callback_data && callback_size) + { + lua_pushlstring(lua, callback_data, callback_size); + lua_setglobal(lua, "_THREAD_CALLBACK"); + } + + // pass callinfo + tb_char_t const* callinfo_data = tb_string_cstr(&thread->callinfo); + tb_size_t callinfo_size = tb_string_size(&thread->callinfo); + if (callinfo_data && callinfo_size) + { + lua_pushlstring(lua, callinfo_data, callinfo_size); + lua_setglobal(lua, "_THREAD_CALLINFO"); + } + + // start engine + tb_char_t* argv[] = {XM_THREAD_ENGINE_NAME, tb_null}; + xm_engine_main(engine, 1, argv, tb_null); + if (!xm_engine_pool_free(xm_engine_pool(), engine)) + xm_engine_exit(engine); + } + return 0; +} + +/* ////////////////////////////////////////////////////////////////////////////////////// + * implementation + */ +tb_int_t xm_thread_init(lua_State* lua) +{ + // check + tb_assert_and_check_return_val(lua, 0); + + tb_bool_t ok = tb_false; + xm_thread_t* thread = tb_null; + do + { + // get thread name + tb_char_t const* name = luaL_checkstring(lua, 1); + + // get callback + size_t callback_size = 0; + tb_char_t const* callback_data = luaL_checklstring(lua, 2, &callback_size); + tb_assert_and_check_break(callback_data && callback_size); + + // get callinfo + size_t callinfo_size = 0; + tb_char_t const* callinfo_data = luaL_checklstring(lua, 3, &callinfo_size); + tb_assert_and_check_break(callinfo_data && callinfo_size); + + // get stack size + tb_size_t stacksize = (tb_size_t)luaL_checkinteger(lua, 4); + + // init thread + thread = tb_malloc0_type(xm_thread_t); + tb_assert_and_check_break(thread); + + tb_string_init(&thread->callback); + tb_string_cstrncpy(&thread->callback, callback_data, callback_size); + + tb_string_init(&thread->callinfo); + tb_string_cstrncpy(&thread->callinfo, callinfo_data, callinfo_size); + + // create and start thread + thread->handle = tb_thread_init(name, xm_thread_func, thread, stacksize); + tb_assert_and_check_break(thread->handle); + + xm_lua_pushpointer(lua, (tb_pointer_t)thread); + ok = tb_true; + + } while (0); + + if (!ok) + { + if (thread) + { + tb_string_exit(&thread->callback); + tb_string_exit(&thread->callinfo); + if (thread->handle) + { + tb_thread_exit(thread->handle); + thread->handle = tb_null; + } + tb_free(thread); + } + lua_pushnil(lua); + } + return 1; +} diff --git a/core/src/xmake/thread/thread_resume.c b/core/src/xmake/thread/thread_resume.c new file mode 100644 index 000000000..9843ac2d7 --- /dev/null +++ b/core/src/xmake/thread/thread_resume.c @@ -0,0 +1,53 @@ +/*!A cross-platform build utility based on Lua + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright (C) 2015-present, Xmake Open Source Community. + * + * @author ruki + * @file thread_resume.c + * + */ + +/* ////////////////////////////////////////////////////////////////////////////////////// + * trace + */ +#define TB_TRACE_MODULE_NAME "thread" +#define TB_TRACE_MODULE_DEBUG (0) + +/* ////////////////////////////////////////////////////////////////////////////////////// + * includes + */ +#include "prefix.h" + +/* ////////////////////////////////////////////////////////////////////////////////////// + * implementation + */ +tb_int_t xm_thread_resume(lua_State* lua) +{ + // check + tb_assert_and_check_return_val(lua, 0); + + // is pointer? + if (!xm_lua_ispointer(lua, 1)) + return 0; + + // get thread + xm_thread_t* thread = (xm_thread_t*)xm_lua_topointer(lua, 1); + tb_check_return_val(thread && thread->handle, 0); + + // resume thread + lua_pushboolean(lua, tb_thread_resume(thread->handle)); + return 1; +} + diff --git a/core/src/xmake/thread/thread_suspend.c b/core/src/xmake/thread/thread_suspend.c new file mode 100644 index 000000000..e21509413 --- /dev/null +++ b/core/src/xmake/thread/thread_suspend.c @@ -0,0 +1,53 @@ +/*!A cross-platform build utility based on Lua + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright (C) 2015-present, Xmake Open Source Community. + * + * @author ruki + * @file thread_suspend.c + * + */ + +/* ////////////////////////////////////////////////////////////////////////////////////// + * trace + */ +#define TB_TRACE_MODULE_NAME "thread" +#define TB_TRACE_MODULE_DEBUG (0) + +/* ////////////////////////////////////////////////////////////////////////////////////// + * includes + */ +#include "prefix.h" + +/* ////////////////////////////////////////////////////////////////////////////////////// + * implementation + */ +tb_int_t xm_thread_suspend(lua_State* lua) +{ + // check + tb_assert_and_check_return_val(lua, 0); + + // is pointer? + if (!xm_lua_ispointer(lua, 1)) + return 0; + + // get thread + xm_thread_t* thread = (xm_thread_t*)xm_lua_topointer(lua, 1); + tb_check_return_val(thread && thread->handle, 0); + + // suspend thread + lua_pushboolean(lua, tb_thread_suspend(thread->handle)); + return 1; +} + diff --git a/core/src/xmake/thread/thread_wait.c b/core/src/xmake/thread/thread_wait.c new file mode 100644 index 000000000..f2d7199ec --- /dev/null +++ b/core/src/xmake/thread/thread_wait.c @@ -0,0 +1,57 @@ +/*!A cross-platform build utility based on Lua + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright (C) 2015-present, Xmake Open Source Community. + * + * @author ruki + * @file thread_wait.c + * + */ + +/* ////////////////////////////////////////////////////////////////////////////////////// + * trace + */ +#define TB_TRACE_MODULE_NAME "thread" +#define TB_TRACE_MODULE_DEBUG (0) + +/* ////////////////////////////////////////////////////////////////////////////////////// + * includes + */ +#include "prefix.h" + +/* ////////////////////////////////////////////////////////////////////////////////////// + * implementation + */ +tb_int_t xm_thread_wait(lua_State* lua) +{ + // check + tb_assert_and_check_return_val(lua, 0); + + // is pointer? + if (!xm_lua_ispointer(lua, 1)) + return 0; + + // get thread + xm_thread_t* thread = (xm_thread_t*)xm_lua_topointer(lua, 1); + tb_check_return_val(thread->handle, 0); + + // get timeout + tb_size_t timeout = (tb_size_t)luaL_checkinteger(lua, 2); + + // wait thread + tb_int_t retval; + lua_pushinteger(lua, (tb_int_t)tb_thread_wait(thread->handle, timeout, &retval)); + return 1; +} + diff --git a/core/src/xmake/xmake.sh b/core/src/xmake/xmake.sh index 6c45b6fa0..731d1d783 100755 --- a/core/src/xmake/xmake.sh +++ b/core/src/xmake/xmake.sh @@ -72,6 +72,7 @@ target "xmake" add_files "string/*.c" add_files "tty/*.c" add_files "utils/*.c" + add_files "thread/*.c" if is_plat "mingw"; then add_files "winos/*.c" fi |
