summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2025-04-28 22:48:18 +0800
committerruki <[email protected]>2025-08-28 11:35:53 +0800
commit2088868b56f2c70cd4e9e72803ced3197ceba010 (patch)
treec98f345d122d4bdbb5b14c37fa843a18d9b2678c
parentc144ca1a86c559af204f0b51c4cf2b2c5afe0d41 (diff)
improve thread callback info
-rw-r--r--core/src/xmake/thread/prefix.h1
-rw-r--r--core/src/xmake/thread/thread_exit.c1
-rw-r--r--core/src/xmake/thread/thread_init.c24
-rw-r--r--xmake/core/_xmake_main.lua1
-rw-r--r--xmake/core/main.lua6
-rw-r--r--xmake/core/thread/thread.lua50
6 files changed, 49 insertions, 34 deletions
diff --git a/core/src/xmake/thread/prefix.h b/core/src/xmake/thread/prefix.h
index 061dca962..1199caa7a 100644
--- a/core/src/xmake/thread/prefix.h
+++ b/core/src/xmake/thread/prefix.h
@@ -34,6 +34,7 @@
typedef struct __xm_thread_t
{
tb_thread_ref_t handle;
+ tb_string_t callback;
tb_string_t callinfo;
}xm_thread_t;
diff --git a/core/src/xmake/thread/thread_exit.c b/core/src/xmake/thread/thread_exit.c
index 881addbd2..dbdefdf90 100644
--- a/core/src/xmake/thread/thread_exit.c
+++ b/core/src/xmake/thread/thread_exit.c
@@ -49,6 +49,7 @@ tb_int_t xm_thread_exit(lua_State* lua)
// exit thread
if (thread)
{
+ tb_string_exit(&thread->callback);
tb_string_exit(&thread->callinfo);
if (thread->handle)
{
diff --git a/core/src/xmake/thread/thread_init.c b/core/src/xmake/thread/thread_init.c
index 8ed5cf90a..a246a6e53 100644
--- a/core/src/xmake/thread/thread_init.c
+++ b/core/src/xmake/thread/thread_init.c
@@ -49,10 +49,19 @@ static tb_int_t xm_thread_func(tb_cpointer_t priv)
xm_engine_ref_t engine = xm_engine_init(XM_THREAD_ENGINE_NAME, tb_null);
if (engine)
{
- // pass callinfo
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)
@@ -85,18 +94,26 @@ tb_int_t xm_thread_init(lua_State* lua)
// 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, 2, &callinfo_size);
+ 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, 3);
+ 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);
@@ -113,6 +130,7 @@ tb_int_t xm_thread_init(lua_State* lua)
{
if (thread)
{
+ tb_string_exit(&thread->callback);
tb_string_exit(&thread->callinfo);
if (thread->handle)
{
diff --git a/xmake/core/_xmake_main.lua b/xmake/core/_xmake_main.lua
index 5d2d8f7a3..a2bbe8e00 100644
--- a/xmake/core/_xmake_main.lua
+++ b/xmake/core/_xmake_main.lua
@@ -36,6 +36,7 @@ xmake._PROJECT_FILE = "xmake.lua"
xmake._WORKING_DIR = os.curdir()
xmake._FEATURES = _FEATURES
xmake._LUAJIT = _LUAJIT
+xmake._THREAD_CALLBACK = _THREAD_CALLBACK
xmake._THREAD_CALLINFO = _THREAD_CALLINFO
-- In order to be compatible with updates from lower versions of engine core
diff --git a/xmake/core/main.lua b/xmake/core/main.lua
index 62ca3de1d..d1b1112a0 100644
--- a/xmake/core/main.lua
+++ b/xmake/core/main.lua
@@ -335,9 +335,9 @@ Or you can add `--root` option or XMAKE_ROOT=y to allow run as root temporarily.
scheduler:enable(true)
-- run task or thread
- local thread_callinfo = xmake._THREAD_CALLINFO
- if thread_callinfo then
- ok, errors = thread._run_thread(thread_callinfo)
+ local thread_callback = xmake._THREAD_CALLBACK
+ if thread_callback then
+ ok, errors = thread._run_thread(thread_callback, xmake._THREAD_CALLINFO)
else
ok, errors = main._run_task(option.taskname() or "build")
end
diff --git a/xmake/core/thread/thread.lua b/xmake/core/thread/thread.lua
index 612af4865..a346566f8 100644
--- a/xmake/core/thread/thread.lua
+++ b/xmake/core/thread/thread.lua
@@ -94,14 +94,12 @@ function _instance:start()
-- serialize and pass callback and arguments to this thread
-- we do not use string.serialize to serialize callback, because it's slower (deserialize)
-- and we cannot strip function debug info, we need to reserve _ENV, and other upvalue names
- local callinfo = string._dump(self._CALLBACK)
- local argv = self._ARGV
- if argv ~= nil then
- callinfo = string.serialize(argv, {strip = true, indent = false}) .. "<Argv\27>" .. callinfo
- end
+ local callback = string._dump(self._CALLBACK)
+ local callinfo = {name = self:name(), argv = self._ARGV}
+ callinfo = string.serialize(callinfo, {strip = true, indent = false})
-- init and start thread
- local handle, errors = thread.thread_init(self:name(), callinfo, self._STACKSIZE)
+ local handle, errors = thread.thread_init(self:name(), callback, callinfo, self._STACKSIZE)
if not handle then
return nil, errors or string.format("%s: failed to create thread!", self)
end
@@ -206,25 +204,31 @@ function thread.running()
end
-- run thread
-function thread._run_thread(callinfo_str)
+function thread._run_thread(callback_str, callinfo_str)
- -- get callinfo
- local parts = callinfo_str:split("<Argv\27>", {plain = true})
- local callback_str, argv_str
- if #parts > 1 then
- callback_str = parts[2]
- argv_str = parts[1]
- else
- callback_str = parts[1]
+ -- load callback info
+ local callinfo
+ local argv
+ local threadname
+ if callinfo_str then
+ local result, errors = string.deserialize(callinfo_str)
+ if not result then
+ return false, string.format("invalid thread callinfo, %s!", errors or "unknown")
+ end
+ callinfo = result
+ if callinfo then
+ argv = callinfo.argv
+ threadname = callinfo.name
+ end
end
- -- load callback, TODO print thread name
+ -- load callback
local callback
local fenvs = {}
if callback_str then
local script, errors = load(callback_str, "=(thread)", "b", fenvs)
if not script then
- return false, string.format("cannot load thread callback, %s!", errors or "unknown")
+ return false, string.format("cannot load thread(%s) callback, %s!", threadname or "unknown", errors or "unknown")
end
for i = 1, math.huge do
local upname, upvalue = debug.getupvalue(script, i)
@@ -232,7 +236,7 @@ function thread._run_thread(callinfo_str)
break
end
if upvalue == nil then
- return false, string.format("we cannot access upvalue(%s) in thread callback!", upname)
+ return false, string.format("we cannot access upvalue(%s) in thread(%s) callback!", upname, threadname or "unknown")
end
end
callback = script
@@ -241,16 +245,6 @@ function thread._run_thread(callinfo_str)
return false, "no thread callback"
end
- -- load argument list
- local argv
- if argv_str then
- local result, errors = string.deserialize(argv_str)
- if not result then
- return false, string.format("invalid thread arguments, %s!", errors or "unknown")
- end
- argv = result
- end
-
-- bind sandbox
-- local sandbox_inst, errors = sandbox.new(callback, {
-- filter = interp:filter(), rootdir = interp:rootdir(), namespace = interp:namespace()})