From 693b962b43b33e752d4a4eb49595802cc6897cd8 Mon Sep 17 00:00:00 2001 From: hong Date: Tue, 1 Dec 2020 11:51:35 +0800 Subject: [PATCH] to-be-closed (#1261) --- lualib/skynet.lua | 16 +++++++++++++- test/testtobeclosed.lua | 48 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 test/testtobeclosed.lua diff --git a/lualib/skynet.lua b/lualib/skynet.lua index d571ea6f..613826d7 100644 --- a/lualib/skynet.lua +++ b/lualib/skynet.lua @@ -14,12 +14,20 @@ local tunpack = table.unpack local traceback = debug.traceback local cresume = coroutine.resume +local coroutine_close = coroutine.close local running_thread = nil local init_thread = nil +local function coroutine_ret(co, ok, ...) + if not ok then + coroutine_close(co) + end + return ok, ... +end + local function coroutine_resume(co, ...) running_thread = co - return cresume(co, ...) + return coroutine_ret(co, cresume(co, ...)) end local coroutine_yield = coroutine.yield local coroutine_create = coroutine.create @@ -329,6 +337,7 @@ function suspend(co, result, command) if command == "SUSPEND" then return dispatch_wakeup() elseif command == "QUIT" then + coroutine_close(co) -- service exit return elseif command == "USER" then @@ -523,6 +532,11 @@ function skynet.exit() c.send(address, skynet.PTYPE_ERROR, session, "") end end + for session, co in pairs(session_id_coroutine) do + if type(co) == "thread" then + coroutine_close(co) + end + end for resp in pairs(unresponse) do resp(false) end diff --git a/test/testtobeclosed.lua b/test/testtobeclosed.lua new file mode 100644 index 00000000..59b9cbe0 --- /dev/null +++ b/test/testtobeclosed.lua @@ -0,0 +1,48 @@ +local skynet = require "skynet" + +local function new_test(name) + return setmetatable({}, { __close = function(...) + skynet.error(...) + end, __name = "closemeta:" .. name}) +end + +local i = 0 +skynet.dispatch("lua", function() + i = i + 1 + if i==2 then + local c = new_test("dispatch_error") + error("dispatch_error") + else + local c = new_test("dispatch_wait") + skynet.wait() + end +end) + +skynet.start(function() + local c = new_test("skynet.exit") + skynet.fork(function() + local a = new_test("stack_raise_error") + error("raise error") + end) + skynet.fork(function() + local a = new_test("session_id_coroutine_wait") + skynet.wait() + end) + skynet.fork(function() + local a = new_test("session_id_coroutine_call") + skynet.call(skynet.self(), "lua") + end) + skynet.fork(function() + skynet.call(skynet.self(), "lua") + end) + skynet.sleep(100) + skynet.fork(function() + local a = new_test("no_running") + skynet.wait() + end) + skynet.exit() +end) + +--[[ +testtobeclosed +]] \ No newline at end of file