diff --git a/lualib/skynet.lua b/lualib/skynet.lua index 03e3c83d..d571ea6f 100644 --- a/lualib/skynet.lua +++ b/lualib/skynet.lua @@ -414,6 +414,59 @@ function skynet.wait(token) session_id_coroutine[session] = nil end +function skynet.killthread(thread) + local session + -- find session + if type(thread) == "string" then + for k,v in pairs(session_id_coroutine) do + local thread_string = tostring(v) + if thread_string:find(thread) then + session = k + break + end + end + else + for i = 1, #fork_queue do + if fork_queue[i] == thread then + tremove(fork_queue, i) + return thread + end + end + for k,v in pairs(session_id_coroutine) do + if v == thread then + session = k + break + end + end + end + local co = session_id_coroutine[session] + if co == nil then + return + end + watching_session[session] = nil + local addr = session_coroutine_address[co] + if addr then + session_coroutine_address[co] = nil + session_coroutine_tracetag[co] = nil + c.send(addr, skynet.PTYPE_ERROR, session_coroutine_id[co], "") + session_coroutine_id[co] = nil + end + if watching_session[session] then + session_id_coroutine[session] = "BREAK" + watching_session[session] = nil + else + session_id_coroutine[session] = nil + end + for k,v in pairs(sleep_session) do + if v == session then + sleep_session[k] = nil + break + end + end + coroutine.close(co) + return co +end + function skynet.self() return c.addresscommand "REG" end @@ -941,10 +994,11 @@ function skynet.task(ret) local tt = type(ret) if tt == "table" then for session,co in pairs(session_id_coroutine) do + local key = string.format("%s session: %d", tostring(co), session) if timeout_traceback and timeout_traceback[co] then - ret[session] = timeout_traceback[co] + ret[key] = timeout_traceback[co] else - ret[session] = traceback(co) + ret[key] = traceback(co) end end return diff --git a/lualib/skynet/debug.lua b/lualib/skynet/debug.lua index b8257135..d8091444 100644 --- a/lualib/skynet/debug.lua +++ b/lualib/skynet/debug.lua @@ -44,6 +44,17 @@ local function init(skynet, export) skynet.ret(skynet.pack(stat)) end + function dbgcmd.KILLTASK(threadname) + local co = skynet.killthread(threadname) + if co then + skynet.error(string.format("Kill %s", co)) + skynet.ret() + else + skynet.error(string.format("Kill %s : Not found", threadname)) + skynet.ret(skynet.pack "Not found") + end + end + function dbgcmd.TASK(session) if session then skynet.ret(skynet.pack(skynet.task(session))) diff --git a/service/debug_console.lua b/service/debug_console.lua index e8b26f68..f0e2a853 100644 --- a/service/debug_console.lua +++ b/service/debug_console.lua @@ -164,6 +164,7 @@ function COMMAND.help() netstat = "netstat : show netstat", profactive = "profactive [on|off] : active/deactive jemalloc heap profilling", dumpheap = "dumpheap : dump heap profilling", + killtask = "killtask address threadname : threadname listed by task", } end @@ -277,6 +278,11 @@ function COMMAND.task(address) return skynet.call(address,"debug","TASK") end +function COMMAND.killtask(address, threadname) + address = adjust_address(address) + return skynet.call(address, "debug", "KILLTASK", threadname) +end + function COMMAND.uniqtask(address) address = adjust_address(address) return skynet.call(address,"debug","UNIQTASK")