diff options
| author | ruki <[email protected]> | 2019-12-11 00:46:15 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2019-12-10 22:37:34 +0800 |
| commit | b6dd6f29f65cab54cfbec2ec234c05abd8ab46bd (patch) | |
| tree | 2a23fda12bde5a8728a9f918657410512cf39ea1 /xmake/core | |
| parent | 965ce42e75869cdec94570a5411b4acd163abe20 (diff) | |
impl scheduler.sleep
Diffstat (limited to 'xmake/core')
| -rw-r--r-- | xmake/core/base/scheduler.lua | 49 | ||||
| -rw-r--r-- | xmake/core/base/timer.lua | 33 | ||||
| -rw-r--r-- | xmake/core/sandbox/modules/import/core/base/scheduler.lua | 13 |
3 files changed, 70 insertions, 25 deletions
diff --git a/xmake/core/base/scheduler.lua b/xmake/core/base/scheduler.lua index 95e727258..52502c066 100644 --- a/xmake/core/base/scheduler.lua +++ b/xmake/core/base/scheduler.lua @@ -27,6 +27,7 @@ local table = require("base/table") local option = require("base/option") local string = require("base/string") local poller = require("base/poller") +local timer = require("base/timer") local coroutine = require("base/coroutine") -- new a coroutine instance @@ -83,15 +84,24 @@ function _coroutine:__gc() self._THREAD = nil end +-- get the timer of scheduler +function scheduler:_timer() + local t = self._TIMER + if t == nil then + t = timer:new() + self._TIMER = t + end + return t +end + -- wait the current coroutine -function scheduler:_co_wait() - -- TODO - self:co_suspend() +function scheduler:_co_wait(...) + return self:co_suspend(...) end -- wake the given coroutine -function scheduler:_co_wake(co) - -- TODO +function scheduler:_co_wake(co, ...) + return self:co_resume(co, ...) end -- start a new coroutine task @@ -146,27 +156,27 @@ end -- sleep some times (ms) function scheduler:sleep(ms) - - print(require("sys")) - print("sleep", ms) - - self:_co_wait() + local running = self:co_running() + if not running then + return false, "we must call sleep() in coroutine with scheduler!" + end + self:_timer():post(function (cancel) + self:co_resume(running) + end, ms) + self:co_suspend() return true end --- the loop is started? -function scheduler:is_started() - return self._STARTED -end - -- stop the scheduler loop function scheduler:stop() -- TODO post a kill signal to poller + -- stop timer and cancel all tasks self._STARTED = false + return true end -- run loop, schedule coroutine with socket/io and sub-processes -function scheduler:runloop(opt) +function scheduler:runloop() -- start loop self._STARTED = true @@ -175,9 +185,12 @@ function scheduler:runloop(opt) opt = opt or {} local ok = true local errors = nil - local timeout = opt.timeout or -1 + local timeout = -1 while self._STARTED do + -- get the next timeout + timeout = self:_timer():delay() or 1000 + -- wait events local count, events = poller:wait(timeout) if count < 0 then @@ -187,7 +200,7 @@ function scheduler:runloop(opt) end -- spank the timer and trigger all timeout tasks - -- TODO + self:_timer():next() -- resume all suspended tasks with events -- TODO diff --git a/xmake/core/base/timer.lua b/xmake/core/base/timer.lua index 28490f01c..7c81f1dd2 100644 --- a/xmake/core/base/timer.lua +++ b/xmake/core/base/timer.lua @@ -37,7 +37,7 @@ end -- post timer task after delay and will be auto-remove it after be expired function timer:post(func, delay, opt) - return self:post_at(task, os.mclock() + delay, delay, opt) + return self:post_at(func, os.mclock() + delay, delay, opt) end -- post timer task at the absolute time and will be auto-remove it after be expired @@ -58,7 +58,7 @@ end -- get the delay of next task function timer:delay() - local delay = -1 + local delay = nil local tasks = self:_tasks() if tasks:length() > 0 then local task = tasks:peek() @@ -70,9 +70,32 @@ function timer:delay() return delay end --- run the timer loop -function timer:runloop() - -- TODO +-- run the timer next loop +function timer:next() + local tasks = self:_tasks() + while tasks:length() > 0 do + local triggered = false + local task = tasks:peek() + if task then + -- timeout? + local now = os.mclock() + if task.when <= now then + tasks:pop() + if task.continuous and not task.cancel then + task.when = now + task.period + tasks:push(task) + end + -- run timer task + if task.func then + task.func(task.cancel) + triggered = true + end + end + end + if not triggered then + break + end + end end -- get timer name diff --git a/xmake/core/sandbox/modules/import/core/base/scheduler.lua b/xmake/core/sandbox/modules/import/core/base/scheduler.lua index ff6576793..0a1189459 100644 --- a/xmake/core/sandbox/modules/import/core/base/scheduler.lua +++ b/xmake/core/sandbox/modules/import/core/base/scheduler.lua @@ -66,9 +66,18 @@ function sandbox_core_base_scheduler.sleep(ms) end end + +-- stop loop +function sandbox_core_base_scheduler.stop() + local ok, errors = scheduler:stop() + if not ok then + raise(errors) + end +end + -- run loop -function sandbox_core_base_scheduler.runloop(opt) - local ok, errors = scheduler:runloop(opt) +function sandbox_core_base_scheduler.runloop() + local ok, errors = scheduler:runloop() if not ok then raise(errors) end |
