summaryrefslogtreecommitdiff
path: root/xmake/core/base/thread.lua
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 /xmake/core/base/thread.lua
parent054c5764447dc51081d466c1bc2e26fda5906712 (diff)
add thread sharedata
Diffstat (limited to 'xmake/core/base/thread.lua')
-rw-r--r--xmake/core/base/thread.lua128
1 files changed, 128 insertions, 0 deletions
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