summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2025-10-04 22:55:08 +0800
committerruki <[email protected]>2025-10-04 22:55:08 +0800
commit1705c0f34f8910c399b680f66dd60f453f91904c (patch)
tree9abd38b4a5e155a2b15a251a4bce5f2f1930e7bb
parentf5cb55bc3ea8333c64e45bdbae2890b6ca1cd3c4 (diff)
add coroutine semaphore
-rw-r--r--xmake/core/base/scheduler.lua42
-rw-r--r--xmake/core/sandbox/modules/import/core/base/scheduler.lua42
2 files changed, 84 insertions, 0 deletions
diff --git a/xmake/core/base/scheduler.lua b/xmake/core/base/scheduler.lua
index 63c9fe009..28c58f3c8 100644
--- a/xmake/core/base/scheduler.lua
+++ b/xmake/core/base/scheduler.lua
@@ -21,6 +21,7 @@
-- define module: scheduler
local scheduler = scheduler or {}
local _coroutine = _coroutine or {}
+local _semaphore = _semaphore or {}
-- load modules
local table = require("base/table")
@@ -33,6 +34,42 @@ local hashset = require("base/hashset")
local coroutine = require("base/coroutine")
local bit = require("base/bit")
+-- new a semaphore instance
+function _semaphore.new(name, value)
+ local instance = table.inherit(_semaphore)
+ instance._NAME = name
+ instance._VALUE = value or 0
+ setmetatable(instance, _semaphore)
+ return instance
+end
+
+-- get the semaphore name
+function _semaphore:name()
+ return self._NAME or "none"
+end
+
+-- get the semaphore value
+function _semaphore:value()
+ return self._VALUE or 0
+end
+
+-- post the semaphore value
+function _semaphore:post(value)
+ value = self._VALUE + value
+ self._VALUE = value
+ return value
+end
+
+-- wait the semaphore
+function _semaphore:wait(timeout)
+ return 0
+end
+
+-- tostring(semaphore)
+function _semaphore:__tostring()
+ return string.format("<sem: %s/%d>", self:name(), self:value())
+end
+
-- new a coroutine instance
function _coroutine.new(name, thread)
local instance = table.inherit(_coroutine)
@@ -726,6 +763,11 @@ function scheduler:co_count()
return self._CO_COUNT or 0
end
+-- new a coroutine semaphore
+function scheduler:co_semaphore(name, value)
+ return _semaphore.new(name, value)
+end
+
-- wait poller object io events, only for socket and pipe object
function scheduler:poller_wait(obj, events, timeout)
diff --git a/xmake/core/sandbox/modules/import/core/base/scheduler.lua b/xmake/core/sandbox/modules/import/core/base/scheduler.lua
index b5d72286c..222bee391 100644
--- a/xmake/core/sandbox/modules/import/core/base/scheduler.lua
+++ b/xmake/core/sandbox/modules/import/core/base/scheduler.lua
@@ -20,6 +20,7 @@
-- define module
local sandbox_core_base_scheduler = sandbox_core_base_scheduler or {}
+local sandbox_core_base_scheduler_semaphore = sandbox_core_base_scheduler_semaphore or {}
-- load modules
local poller = require("base/poller")
@@ -31,6 +32,41 @@ sandbox_core_base_scheduler.OT_SOCK = poller.OT_SOCK
sandbox_core_base_scheduler.OT_PIPE = poller.OT_PIPE
sandbox_core_base_scheduler.OT_PROC = poller.OT_PROC
+-- wrap semaphore
+function _semaphore_wrap(semaphore)
+
+ -- hook semaphore interfaces
+ local hooked = {}
+ for name, func in pairs(sandbox_core_base_scheduler_semaphore) do
+ if not name:startswith("_") and type(func) == "function" then
+ hooked["_" .. name] = semaphore["_" .. name] or semaphore[name]
+ hooked[name] = func
+ end
+ end
+ for name, func in pairs(hooked) do
+ semaphore[name] = func
+ end
+ return semaphore
+end
+
+-- post semaphore
+function sandbox_core_base_scheduler_semaphore.post(semaphore, value)
+ local result, errors = semaphore:_post(value)
+ if result < 0 and errors then
+ raise(errors)
+ end
+ return result
+end
+
+-- wait semaphore
+function sandbox_core_base_scheduler_semaphore.wait(semaphore, timeout)
+ local ok, errors = semaphore:_wait(timeout)
+ if ok < 0 and errors then
+ raise(errors)
+ end
+ return ok
+end
+
-- start a new coroutine task
function sandbox_core_base_scheduler.co_start(cotask, ...)
local co, errors = scheduler:co_start(cotask, ...)
@@ -136,5 +172,11 @@ function sandbox_core_base_scheduler.co_count()
return scheduler:co_count()
end
+-- new a coroutine semaphore
+function sandbox_core_base_scheduler.co_semaphore(name, value)
+ local semaphore = scheduler:co_semaphore(name, value)
+ return _semaphore_wrap(semaphore)
+end
+
-- return module
return sandbox_core_base_scheduler