summaryrefslogtreecommitdiff
path: root/xmake/core/base
diff options
context:
space:
mode:
authorruki <[email protected]>2019-12-11 00:46:15 +0800
committerruki <[email protected]>2019-12-10 22:37:34 +0800
commitb6dd6f29f65cab54cfbec2ec234c05abd8ab46bd (patch)
tree2a23fda12bde5a8728a9f918657410512cf39ea1 /xmake/core/base
parent965ce42e75869cdec94570a5411b4acd163abe20 (diff)
impl scheduler.sleep
Diffstat (limited to 'xmake/core/base')
-rw-r--r--xmake/core/base/scheduler.lua49
-rw-r--r--xmake/core/base/timer.lua33
2 files changed, 59 insertions, 23 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