summaryrefslogtreecommitdiff
path: root/core/src
diff options
context:
space:
mode:
authorruki <[email protected]>2025-09-02 10:16:24 +0800
committerGitHub <[email protected]>2025-09-02 10:16:24 +0800
commit148501afafa5e9e05da7a54bc804880d6c415849 (patch)
treef5cbcee2b05d4b836478a45698c8a42b43ea38b7 /core/src
parent90b7015682c5523dfa252ebfbab6ed16b3e4b16a (diff)
parent37a499eeb5fd84be4ac83d639211e18e55dccd32 (diff)
Merge pull request #6324 from xmake-io/thread
Add native thread support
Diffstat (limited to 'core/src')
m---------core/src/tbox/tbox0
-rw-r--r--core/src/xmake/engine.c161
-rw-r--r--core/src/xmake/engine.h26
-rw-r--r--core/src/xmake/engine_pool.c107
-rw-r--r--core/src/xmake/engine_pool.h82
-rw-r--r--core/src/xmake/io/pipe_close.c4
-rw-r--r--core/src/xmake/io/pipe_read.c4
-rw-r--r--core/src/xmake/io/pipe_wait.c4
-rw-r--r--core/src/xmake/io/pipe_write.c4
-rw-r--r--core/src/xmake/io/poller.c34
-rw-r--r--core/src/xmake/io/poller.h14
-rw-r--r--core/src/xmake/io/poller_insert.c2
-rw-r--r--core/src/xmake/io/poller_modify.c2
-rw-r--r--core/src/xmake/io/poller_remove.c2
-rw-r--r--core/src/xmake/io/poller_spank.c2
-rw-r--r--core/src/xmake/io/poller_support.c2
-rw-r--r--core/src/xmake/io/poller_wait.c55
-rw-r--r--core/src/xmake/io/prefix.h15
-rw-r--r--core/src/xmake/io/socket_close.c2
-rw-r--r--core/src/xmake/thread/event_exit.c55
-rw-r--r--core/src/xmake/thread/event_incref.c46
-rw-r--r--core/src/xmake/thread/event_init.c70
-rw-r--r--core/src/xmake/thread/event_post.c46
-rw-r--r--core/src/xmake/thread/event_wait.c47
-rw-r--r--core/src/xmake/thread/mutex_exit.c55
-rw-r--r--core/src/xmake/thread/mutex_incref.c46
-rw-r--r--core/src/xmake/thread/mutex_init.c70
-rw-r--r--core/src/xmake/thread/mutex_lock.c46
-rw-r--r--core/src/xmake/thread/mutex_trylock.c46
-rw-r--r--core/src/xmake/thread/mutex_unlock.c46
-rw-r--r--core/src/xmake/thread/prefix.h156
-rw-r--r--core/src/xmake/thread/queue_clear.c47
-rw-r--r--core/src/xmake/thread/queue_exit.c55
-rw-r--r--core/src/xmake/thread/queue_incref.c46
-rw-r--r--core/src/xmake/thread/queue_init.c87
-rw-r--r--core/src/xmake/thread/queue_pop.c92
-rw-r--r--core/src/xmake/thread/queue_push.c96
-rw-r--r--core/src/xmake/thread/queue_size.c46
-rw-r--r--core/src/xmake/thread/semaphore_exit.c55
-rw-r--r--core/src/xmake/thread/semaphore_incref.c46
-rw-r--r--core/src/xmake/thread/semaphore_init.c72
-rw-r--r--core/src/xmake/thread/semaphore_post.c47
-rw-r--r--core/src/xmake/thread/semaphore_wait.c47
-rw-r--r--core/src/xmake/thread/sharedata_clear.c48
-rw-r--r--core/src/xmake/thread/sharedata_exit.c51
-rw-r--r--core/src/xmake/thread/sharedata_get.c82
-rw-r--r--core/src/xmake/thread/sharedata_incref.c46
-rw-r--r--core/src/xmake/thread/sharedata_init.c66
-rw-r--r--core/src/xmake/thread/sharedata_set.c84
-rw-r--r--core/src/xmake/thread/thread_exit.c64
-rw-r--r--core/src/xmake/thread/thread_init.c146
-rw-r--r--core/src/xmake/thread/thread_resume.c53
-rw-r--r--core/src/xmake/thread/thread_suspend.c53
-rw-r--r--core/src/xmake/thread/thread_wait.c57
-rwxr-xr-xcore/src/xmake/xmake.sh1
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