From f425d10c8be310140a2063a93223593c22ddb70b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BA=91=E9=A3=8E?= Date: Mon, 27 Aug 2012 12:07:19 +0800 Subject: [PATCH] timer wakeup --- lualib/skynet.lua | 45 +++++++++++++++++++++++++++++++++++++++---- service/testtimer.lua | 14 +++++++++++--- 2 files changed, 52 insertions(+), 7 deletions(-) diff --git a/lualib/skynet.lua b/lualib/skynet.lua index 85e7883f..6bc0e164 100644 --- a/lualib/skynet.lua +++ b/lualib/skynet.lua @@ -3,29 +3,54 @@ local tostring = tostring local tonumber = tonumber local coroutine = coroutine local assert = assert +local pairs = pairs local skynet = {} local session_id_coroutine = {} local session_coroutine_id = {} local session_coroutine_address = {} -local function suspend(co, result, command, param, size) +local wakeup_session = {} +local sleep_session = {} + +-- suspend is function +local suspend + +local function dispatch_wakeup() + local co = next(wakeup_session) + if co then + wakeup_session[co] = nil + local session = sleep_session[co] + if session then + session_id_coroutine[session] = "BREAK" + return suspend(co, coroutine.resume(co, true)) + end + end +end + +-- suspend is local function +function suspend(co, result, command, param, size) if not result then error(debug.traceback(co,command)) end - if command == "CALL" or command == "SLEEP" then + if command == "CALL" then session_id_coroutine[param] = co + elseif command == "SLEEP" then + session_id_coroutine[param] = co + sleep_session[co] = param elseif command == "RETURN" then local co_session = session_coroutine_id[co] local co_address = session_coroutine_address[co] c.send(co_address, co_session, param, size) return suspend(co, coroutine.resume(co)) elseif command == nil then + -- coroutine exit session_coroutine_id[co] = nil session_coroutine_address[co] = nil else error("Unknown command : " .. command .. "\n" .. debug.traceback(co)) end + dispatch_wakeup() end function skynet.timeout(ti, func, ...) @@ -52,13 +77,16 @@ end function skynet.sleep(ti) local session = c.command("TIMEOUT",tostring(ti)) assert(session) - coroutine.yield("SLEEP", tonumber(session)) + local ret = coroutine.yield("SLEEP", tonumber(session)) + sleep_session[coroutine.running()] = nil + return ret end function skynet.yield() local session = c.command("TIMEOUT","0") assert(session) coroutine.yield("SLEEP", tonumber(session)) + sleep_session[coroutine.running()] = nil end function skynet.register(name) @@ -146,7 +174,9 @@ local function default_dispatch(f, unknown) suspend(co, coroutine.resume(co, msg, sz, session, address)) else local co = session_id_coroutine[session] - if co == nil then + if co == "BREAK" then + session_id_coroutine[session] = nil + elseif co == nil then unknown(session,msg,sz) else session_id_coroutine[session] = nil @@ -156,6 +186,13 @@ local function default_dispatch(f, unknown) end end +function skynet.wakeup(co) + if sleep_session[co] and wakeup_session[co] == nil then + wakeup_session[co] = true + return true + end +end + function skynet.dispatch(f,unknown) c.callback(default_dispatch(f,unknown)) end diff --git a/service/testtimer.lua b/service/testtimer.lua index 54c289e4..b98cd6f6 100644 --- a/service/testtimer.lua +++ b/service/testtimer.lua @@ -7,11 +7,19 @@ local function timeout(t) print(t) end +local function wakeup(co) + for i=1,5 do + skynet.sleep(50) + skynet.wakeup(co) + end +end + skynet.start(function() - skynet.timeout(500, timeout, "Hello World") + skynet.fork(wakeup, coroutine.running()) + skynet.timeout(300, timeout, "Hello World") for i = 1, 10 do - print(i) - skynet.sleep(100) + print(i, skynet.now()) + print(skynet.sleep(100)) end skynet.exit() print("Test timer exit")