summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2025-08-29 23:20:48 +0800
committerruki <[email protected]>2025-08-29 23:20:48 +0800
commitf1d54d70a80b86465c2df36eb95a0bcda8c26824 (patch)
treea351724ed7b43246e21d20720b577557df764ba6
parent054c5764447dc51081d466c1bc2e26fda5906712 (diff)
add thread sharedata
-rw-r--r--core/src/xmake/engine.c14
-rw-r--r--core/src/xmake/thread/prefix.h64
-rw-r--r--core/src/xmake/thread/queue_clear.c2
-rw-r--r--core/src/xmake/thread/queue_init.c8
-rw-r--r--core/src/xmake/thread/queue_pop.c14
-rw-r--r--core/src/xmake/thread/queue_push.c14
-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--tests/modules/thread/sharedata.lua26
-rw-r--r--xmake/core/base/thread.lua128
-rw-r--r--xmake/core/sandbox/modules/import/core/base/thread.lua57
15 files changed, 662 insertions, 42 deletions
diff --git a/core/src/xmake/engine.c b/core/src/xmake/engine.c
index d3d48c7cc..ee07da6ea 100644
--- a/core/src/xmake/engine.c
+++ b/core/src/xmake/engine.c
@@ -377,6 +377,14 @@ 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);
@@ -694,6 +702,12 @@ static luaL_Reg const g_thread_functions[] =
, { "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 }
};
diff --git a/core/src/xmake/thread/prefix.h b/core/src/xmake/thread/prefix.h
index 8fc303b10..2b841e6a7 100644
--- a/core/src/xmake/thread/prefix.h
+++ b/core/src/xmake/thread/prefix.h
@@ -39,6 +39,32 @@ typedef struct __xm_thread_t
}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
{
@@ -71,31 +97,14 @@ typedef struct __xm_thread_queue_t
}xm_thread_queue_t;
-// the thread queue item kind
-typedef enum __xm_thread_queue_item_kind_e
+// the thread sharedata type
+typedef struct __xm_thread_sharedata_t
{
- XM_THREAD_QUEUE_ITEM_NIL = 0,
- XM_THREAD_QUEUE_ITEM_BOOL = 1,
- XM_THREAD_QUEUE_ITEM_INT = 2,
- XM_THREAD_QUEUE_ITEM_NUM = 3,
- XM_THREAD_QUEUE_ITEM_STR = 4
+ xm_thread_value_t value;
+ tb_buffer_t buffer;
+ tb_atomic_t refn;
-}xm_thread_queue_item_kind_e;
-
-// the thread queue item type
-typedef struct __xm_thread_queue_item_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_queue_item_t;
+}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)
@@ -133,6 +142,15 @@ static __tb_inline__ xm_thread_queue_t* xm_thread_queue_get(lua_State* lua, tb_i
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
index bf70d12e1..4888babe2 100644
--- a/core/src/xmake/thread/queue_clear.c
+++ b/core/src/xmake/thread/queue_clear.c
@@ -15,7 +15,7 @@
* Copyright (C) 2015-present, Xmake Open Source Community.
*
* @author ruki
- * @file thread_queue_lock.c
+ * @file thread_queue_clear.c
*
*/
diff --git a/core/src/xmake/thread/queue_init.c b/core/src/xmake/thread/queue_init.c
index 4c4e9a9f6..0c8af884d 100644
--- a/core/src/xmake/thread/queue_init.c
+++ b/core/src/xmake/thread/queue_init.c
@@ -33,12 +33,12 @@
/* //////////////////////////////////////////////////////////////////////////////////////
* private implementation
*/
-static tb_void_t xm_thread_queue_item_free(tb_element_ref_t element, tb_pointer_t buff)
+static tb_void_t xm_thread_value_free(tb_element_ref_t element, tb_pointer_t buff)
{
- xm_thread_queue_item_t* item = (xm_thread_queue_item_t*)buff;
+ xm_thread_value_t* item = (xm_thread_value_t*)buff;
if (item)
{
- if (item->kind == XM_THREAD_QUEUE_ITEM_STR)
+ if (item->kind == XM_THREAD_VALUE_STR)
{
if (item->u.string) tb_free((tb_pointer_t)item->u.string);
item->u.string = tb_null;
@@ -62,7 +62,7 @@ tb_int_t xm_thread_queue_init(lua_State* lua)
tb_assert_and_check_break(thread_queue);
thread_queue->refn = 1;
- thread_queue->handle = tb_queue_init(0, tb_element_mem(sizeof(xm_thread_queue_item_t), xm_thread_queue_item_free, tb_null));
+ 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);
diff --git a/core/src/xmake/thread/queue_pop.c b/core/src/xmake/thread/queue_pop.c
index 4e205bab4..c666a85dd 100644
--- a/core/src/xmake/thread/queue_pop.c
+++ b/core/src/xmake/thread/queue_pop.c
@@ -15,7 +15,7 @@
* Copyright (C) 2015-present, Xmake Open Source Community.
*
* @author ruki
- * @file thread_queue_unlock.c
+ * @file thread_queue_pop.c
*
*/
@@ -47,31 +47,31 @@ tb_int_t xm_thread_queue_pop(lua_State* lua)
return 2;
}
- xm_thread_queue_item_t* item = (xm_thread_queue_item_t*)tb_queue_get(thread_queue->handle);
+ 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_QUEUE_ITEM_STR:
+ 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_QUEUE_ITEM_INT:
+ case XM_THREAD_VALUE_INT:
lua_pushinteger(lua, item->u.integer);
ok = tb_true;
break;
- case XM_THREAD_QUEUE_ITEM_NUM:
+ case XM_THREAD_VALUE_NUM:
lua_pushnumber(lua, item->u.number);
ok = tb_true;
break;
- case XM_THREAD_QUEUE_ITEM_BOOL:
+ case XM_THREAD_VALUE_BOOL:
lua_pushboolean(lua, item->u.boolean);
ok = tb_true;
break;
- case XM_THREAD_QUEUE_ITEM_NIL:
+ case XM_THREAD_VALUE_NIL:
lua_pushnil(lua);
ok = tb_true;
break;
diff --git a/core/src/xmake/thread/queue_push.c b/core/src/xmake/thread/queue_push.c
index b1cf78132..8125f2b9a 100644
--- a/core/src/xmake/thread/queue_push.c
+++ b/core/src/xmake/thread/queue_push.c
@@ -15,7 +15,7 @@
* Copyright (C) 2015-present, Xmake Open Source Community.
*
* @author ruki
- * @file thread_queue_lock.c
+ * @file thread_queue_push.c
*
*/
@@ -47,14 +47,14 @@ tb_int_t xm_thread_queue_push(lua_State* lua)
return 2;
}
- xm_thread_queue_item_t item;
+ 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_QUEUE_ITEM_STR;
+ item.kind = (tb_uint32_t)XM_THREAD_VALUE_STR;
item.size = (tb_uint32_t)data_size;
if (data_size)
{
@@ -65,22 +65,22 @@ tb_int_t xm_thread_queue_push(lua_State* lua)
}
else if (xm_lua_isinteger(lua, 2))
{
- item.kind = (tb_uint32_t)XM_THREAD_QUEUE_ITEM_INT;
+ 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_QUEUE_ITEM_NUM;
+ 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_QUEUE_ITEM_BOOL;
+ 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_QUEUE_ITEM_NIL;
+ item.kind = (tb_uint32_t)XM_THREAD_VALUE_NIL;
}
else
{
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..66d7d9e04
--- /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, 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/tests/modules/thread/sharedata.lua b/tests/modules/thread/sharedata.lua
new file mode 100644
index 000000000..cce265ae1
--- /dev/null
+++ b/tests/modules/thread/sharedata.lua
@@ -0,0 +1,26 @@
+import("core.base.thread")
+
+function callback(event, sharedata)
+ print("starting ..")
+ while true do
+ print("waiting ..")
+ if event:wait(-1) > 0 then
+ print(" -> %s", sharedata:get())
+ end
+ end
+end
+
+function main()
+ local event = thread.event()
+ local sharedata = thread.sharedata()
+ local t = thread.start_named("", callback, event, sharedata)
+ while true do
+ local ch = io.read()
+ if ch then
+ sharedata:set(ch)
+ event:post()
+ end
+ end
+ t:wait(-1)
+end
+
diff --git a/xmake/core/base/thread.lua b/xmake/core/base/thread.lua
index 3697c580a..950712de2 100644
--- a/xmake/core/base/thread.lua
+++ b/xmake/core/base/thread.lua
@@ -25,6 +25,7 @@ local _mutex = _mutex or {}
local _event = _event or {}
local _semaphore = _semaphore or {}
local _queue = _queue or {}
+local _sharedata = _sharedata or {}
-- load modules
local io = require("base/io")
@@ -116,6 +117,10 @@ function _thread:start()
elseif type(arg) == "table" and arg._QUEUE and arg.cdata then
thread.queue_incref(arg:cdata())
arg = {queue = true, name = arg:name(), caddr = libc.dataptr(arg:cdata())}
+ -- is sharedata? we can only pass cdata address
+ elseif type(arg) == "table" and arg._SHAREDATA and arg.cdata then
+ thread.sharedata_incref(arg:cdata())
+ arg = {sharedata = true, name = arg:name(), caddr = libc.dataptr(arg:cdata())}
end
table.insert(argv, arg)
end
@@ -647,6 +652,117 @@ function _queue:__gc()
end
end
+-- new an sharedata
+function _sharedata.new(name, cdata)
+ local sharedata = table.inherit(_sharedata)
+ sharedata._NAME = name
+ sharedata._SHAREDATA = cdata
+ setmetatable(sharedata, _sharedata)
+ return sharedata
+end
+
+-- get the sharedata name
+function _sharedata:name()
+ return self._NAME
+end
+
+-- get the cdata
+function _sharedata:cdata()
+ return self._SHAREDATA
+end
+
+-- clear sharedata
+function _sharedata:clear()
+ local ok, errors = self:_ensure_opened()
+ if not ok then
+ return false, errors
+ end
+
+ local ok, errors = thread.sharedata_clear(self:cdata())
+ if not ok then
+ return false, string.format("%s: clear failed, errors: %s!", self, errors or "unknown")
+ end
+ return ok
+end
+
+-- set sharedata
+function _sharedata:set(value)
+ local ok, errors = self:_ensure_opened()
+ if not ok then
+ return false, errors
+ end
+
+ if type(value) == "table" then
+ value = string.serialize(value, {strip = true, indent = false})
+ if value == nil then
+ return false, string.format("%s: cannot serialize value: %s", self, value)
+ end
+ value = "__table_" .. value
+ end
+
+ local ok, errors = thread.sharedata_set(self:cdata(), value)
+ if not ok then
+ return false, string.format("%s: set sharedata failed, errors: %s!", self, errors or "unknown")
+ end
+ return ok
+end
+
+-- get sharedata
+function _sharedata:get()
+ local ok, errors = self:_ensure_opened()
+ if not ok then
+ return nil, errors or "unknown"
+ end
+
+ local value, errors = thread.sharedata_get(self:cdata())
+ if value == nil and errors then
+ return nil, string.format("%s: get sharedata failed, errors: %s!", self, errors or "unknown")
+ end
+
+ if type(value) == "string" and value:startswith("__table_") then
+ value = value:sub(9)
+ value, errors = string.deserialize(value)
+ if not value then
+ return nil, string.format("invalid sharedata, %s!", errors or "unknown")
+ end
+ end
+ return value
+end
+
+-- close sharedata
+function _sharedata:close()
+ local ok, errors = self:_ensure_opened()
+ if not ok then
+ return false, errors
+ end
+
+ ok = thread.sharedata_exit(self:cdata())
+ if ok then
+ self._SHAREDATA = nil
+ end
+ return ok
+end
+
+-- ensure the file is opened
+function _sharedata:_ensure_opened()
+ if not self:cdata() then
+ return false, string.format("%s: has been closed!", self)
+ end
+ return true
+end
+
+-- tostring(sharedata)
+function _sharedata:__tostring()
+ return "<sharedata: " .. (self:name() or tostring(self:cdata())) .. ">"
+end
+
+-- gc(sharedata)
+function _sharedata:__gc()
+ if self:cdata() and thread.sharedata_exit(self:cdata()) then
+ self._SHAREDATA = nil
+ end
+end
+
-- new a thread
--
-- @param callback the thread callback
@@ -731,6 +847,8 @@ function thread._run_thread(callback_str, callinfo_str)
arg = _semaphore.new(arg.name, libc.ptraddr(arg.caddr))
elseif type(arg) == "table" and arg.queue and arg.caddr then
arg = _queue.new(arg.name, libc.ptraddr(arg.caddr))
+ elseif type(arg) == "table" and arg.sharedata and arg.caddr then
+ arg = _sharedata.new(arg.name, libc.ptraddr(arg.caddr))
end
table.insert(newargv, arg)
end
@@ -790,6 +908,16 @@ function thread.queue(name)
end
end
+-- open a sharedata
+function thread.sharedata(name)
+ local sharedata = thread.sharedata_init()
+ if sharedata then
+ return _sharedata.new(name, sharedata)
+ else
+ return nil, string.format("cannot open sharedata: %s", os.strerror())
+ end
+end
+
-- return module
return thread
diff --git a/xmake/core/sandbox/modules/import/core/base/thread.lua b/xmake/core/sandbox/modules/import/core/base/thread.lua
index a10dc1511..21e068964 100644
--- a/xmake/core/sandbox/modules/import/core/base/thread.lua
+++ b/xmake/core/sandbox/modules/import/core/base/thread.lua
@@ -31,6 +31,7 @@ local sandbox_core_base_thread_mutex = sandbox_core_base_thread_mutex or {}
local sandbox_core_base_thread_event = sandbox_core_base_thread_event or {}
local sandbox_core_base_thread_semaphore = sandbox_core_base_thread_semaphore or {}
local sandbox_core_base_thread_queue = sandbox_core_base_thread_queue or {}
+local sandbox_core_base_thread_sharedata = sandbox_core_base_thread_sharedata or {}
-- export the thread status
sandbox_core_base_thread.STATUS_READY = thread.STATUS_READY
@@ -215,6 +216,41 @@ function sandbox_core_base_thread_queue.close(queue)
end
end
+-- clear sharedata
+function sandbox_core_base_thread_sharedata.clear(sharedata)
+ local ok, errors = sharedata:_clear()
+ if not ok then
+ raise(errors)
+ end
+ return ok
+end
+
+-- set sharedata
+function sandbox_core_base_thread_sharedata.set(sharedata, value)
+ local ok, errors = sharedata:_set(value)
+ if not ok then
+ raise(errors)
+ end
+ return ok
+end
+
+-- get sharedata
+function sandbox_core_base_thread_sharedata.get(sharedata)
+ local value, errors = sharedata:_get()
+ if value == nil and errors then
+ raise(errors)
+ end
+ return value
+end
+
+-- close sharedata
+function sandbox_core_base_thread_sharedata.close(sharedata)
+ local ok, errors = sharedata:_close()
+ if not ok then
+ raise(errors)
+ end
+end
+
-- new thread
function sandbox_core_base_thread.new(callback, opt)
local instance, errors = thread.new(callback, opt)
@@ -332,6 +368,27 @@ function sandbox_core_base_thread.queue(name)
return queue
end
+-- open a sharedata
+function sandbox_core_base_thread.sharedata(name)
+ local sharedata, errors = thread.sharedata(name)
+ if not sharedata then
+ raise(errors)
+ end
+
+ -- hook filesharedata interfaces
+ local hooked = {}
+ for name, func in pairs(sandbox_core_base_thread_sharedata) do
+ if not name:startswith("_") and type(func) == "function" then
+ hooked["_" .. name] = sharedata["_" .. name] or sharedata[name]
+ hooked[name] = func
+ end
+ end
+ for name, func in pairs(hooked) do
+ sharedata[name] = func
+ end
+ return sharedata
+end
+
-- return module
return sandbox_core_base_thread