diff options
| author | ruki <[email protected]> | 2020-02-04 00:35:32 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2020-02-07 22:45:56 +0800 |
| commit | 486cc3bb146e19542991fd2ac3ac385f101bde1a (patch) | |
| tree | 1c455d39efd6489ceccdb6c1c9b902a7a60da8a4 | |
| parent | 81f94cfcc81beb8a0218506108813ceeb7eb9048 (diff) | |
add scheduler.co_yield
| -rw-r--r-- | tests/modules/scheduler/sleep.lua | 26 | ||||
| -rw-r--r-- | tests/modules/scheduler/yield.lua | 15 | ||||
| -rw-r--r-- | xmake/core/base/scheduler.lua | 103 | ||||
| -rw-r--r-- | xmake/core/sandbox/modules/import/core/base/scheduler.lua | 13 | ||||
| -rw-r--r-- | xmake/core/sandbox/modules/os.lua | 2 |
5 files changed, 124 insertions, 35 deletions
diff --git a/tests/modules/scheduler/sleep.lua b/tests/modules/scheduler/sleep.lua new file mode 100644 index 000000000..5c6976a07 --- /dev/null +++ b/tests/modules/scheduler/sleep.lua @@ -0,0 +1,26 @@ +import("core.base.scheduler") + +function _session2(id) + print("session2: %d ..", id) + local dt = os.mclock() + os.sleep(1000) + dt = os.mclock() - dt + print("session2: %d end, dt: %d ms", id, dt) +end + +function _session1(id) + print("session1: %d ..", id) + local dt = os.mclock() + scheduler.co_sleep(1000) + dt = os.mclock() - dt + print("session1: %d end, dt: %d ms", id, dt) +end + +function main() + for i = 1, 10 do + scheduler.co_start(_session1, i) + scheduler.co_start(_session2, i) + end + scheduler.runloop() +end + diff --git a/tests/modules/scheduler/yield.lua b/tests/modules/scheduler/yield.lua new file mode 100644 index 000000000..f884a0199 --- /dev/null +++ b/tests/modules/scheduler/yield.lua @@ -0,0 +1,15 @@ +import("core.base.scheduler") + +function _session(id) + print("test: %d ..", id) + scheduler.co_yield() + print("test: %d end", id) +end + +function main() + for i = 1, 10 do + scheduler.co_start(_session, i) + end + scheduler.runloop() +end + diff --git a/xmake/core/base/scheduler.lua b/xmake/core/base/scheduler.lua index 1464ae2dc..1c6db570d 100644 --- a/xmake/core/base/scheduler.lua +++ b/xmake/core/base/scheduler.lua @@ -251,6 +251,13 @@ end -- start a new named coroutine task function scheduler:co_start_named(coname, cotask, ...) + + -- check coroutine task + if not cotask then + return nil, string.format("cannot start coroutine, invalid cotask(%s/%s)", coname and coname or "anonymous", cotask) + end + + -- start coroutine local co co = _coroutine.new(coname, coroutine.create(function(...) cotask(...) @@ -283,6 +290,71 @@ function scheduler:co_suspend(...) return coroutine.yield(...) end +-- yield the current coroutine +function scheduler:co_yield() + + -- get the running coroutine + local running = self:co_running() + if not running then + return false, "we must call co_yield() in coroutine with scheduler!" + end + + -- is stopped? + if not self._STARTED then + return false, "the scheduler is stopped!" + end + + -- register timeout task to timer without 0 ms (no delay) + self:_timer():post(function (cancel) + if running:is_suspended() then + self:_co_tasks_suspended():remove(running) + self:co_resume(running) + end + end, 0) + + -- save the suspended coroutine + self:_co_tasks_suspended():insert(running) + + -- wait + self:co_suspend() + return true +end + +-- sleep some times (ms) +function scheduler:co_sleep(ms) + + -- we need not do sleep + if ms == 0 then + return true + end + + -- get the running coroutine + local running = self:co_running() + if not running then + return false, "we must call sleep() in coroutine with scheduler!" + end + + -- is stopped? + if not self._STARTED then + return false, "the scheduler is stopped!" + end + + -- register timeout task to timer + self:_timer():post(function (cancel) + if running:is_suspended() then + self:_co_tasks_suspended():remove(running) + self:co_resume(running) + end + end, ms) + + -- save the suspended coroutine + self:_co_tasks_suspended():insert(running) + + -- wait + self:co_suspend() + return true +end + -- get the current running coroutine function scheduler:co_running() local running = coroutine.running() @@ -499,37 +571,6 @@ function scheduler:poller_cancel(obj) return true end --- sleep some times (ms) -function scheduler:sleep(ms) - - -- we need not do sleep - if ms == 0 then - return true - end - - -- get the running coroutine - local running = self:co_running() - if not running then - return false, "we must call sleep() in coroutine with scheduler!" - end - - -- is stopped? - if not self._STARTED then - return false, "the scheduler is stopped!" - end - - -- register timeout task to timer - self:_timer():post(function (cancel) - if running:is_suspended() then - self:co_resume(running) - end - end, ms) - - -- wait - self:co_suspend() - return true -end - -- stop the scheduler loop function scheduler:stop() -- mark scheduler status as stopped and spank the poller:wait() diff --git a/xmake/core/sandbox/modules/import/core/base/scheduler.lua b/xmake/core/sandbox/modules/import/core/base/scheduler.lua index cdd1ad586..3476c9333 100644 --- a/xmake/core/sandbox/modules/import/core/base/scheduler.lua +++ b/xmake/core/sandbox/modules/import/core/base/scheduler.lua @@ -53,6 +53,14 @@ function sandbox_core_base_scheduler.co_suspend(...) return scheduler:co_suspend(...) end +-- yield the current coroutine +function sandbox_core_base_scheduler.co_yield() + local ok, errors = scheduler:co_yield() + if not ok then + raise(errors) + end +end + -- get the current running coroutine function sandbox_core_base_scheduler.co_running() return scheduler:co_running() @@ -64,14 +72,13 @@ function sandbox_core_base_scheduler.co_count() end -- sleep some times (ms) -function sandbox_core_base_scheduler.sleep(ms) - local ok, errors = scheduler:sleep(ms) +function sandbox_core_base_scheduler.co_sleep(ms) + local ok, errors = scheduler:co_sleep(ms) if not ok then raise(errors) end end - -- stop loop function sandbox_core_base_scheduler.stop() local ok, errors = scheduler:stop() diff --git a/xmake/core/sandbox/modules/os.lua b/xmake/core/sandbox/modules/os.lua index 10323b438..b69c68f25 100644 --- a/xmake/core/sandbox/modules/os.lua +++ b/xmake/core/sandbox/modules/os.lua @@ -484,7 +484,7 @@ end -- sleep (support in coroutine) function sandbox_os.sleep(ms) if scheduler:co_running() then - local ok, errors = scheduler:sleep(ms) + local ok, errors = scheduler:co_sleep(ms) if not ok then raise(errors) end |
