From 5a1b2e51f723722b2e6774fe8021da4b45df40a2 Mon Sep 17 00:00:00 2001 From: Cloud Wu Date: Wed, 23 Dec 2015 19:55:42 +0800 Subject: [PATCH] exit dispatch_by_order when close channel --- lualib/socketchannel.lua | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/lualib/socketchannel.lua b/lualib/socketchannel.lua index 31a339c5..7a9b74fc 100644 --- a/lualib/socketchannel.lua +++ b/lualib/socketchannel.lua @@ -68,14 +68,21 @@ local function wakeup_all(self, errmsg) for i = 1, #self.__thread do local co = self.__thread[i] self.__thread[i] = nil - self.__result[co] = socket_error - self.__result_data[co] = errmsg - skynet.wakeup(co) + if co then -- ignore the close signal + self.__result[co] = socket_error + self.__result_data[co] = errmsg + skynet.wakeup(co) + end end end end - +local function exit_thread(self) + local co = coroutine.running() + if self.__dispatch_thread == co then + self.__dispatch_thread = nil + end +end local function dispatch_by_session(self) local response = self.__response @@ -113,6 +120,7 @@ local function dispatch_by_session(self) wakeup_all(self, errormsg) end end + exit_thread(self) end local function pop_response(self) @@ -144,6 +152,11 @@ end local function dispatch_by_order(self) while self.__sock do local func, co = pop_response(self) + if not co then + -- close signal + wakeup_all(self, errmsg) + break + end local ok, result_ok, result_data, padding = pcall(func, self.__sock) if ok then if padding and result_ok then @@ -173,6 +186,7 @@ local function dispatch_by_order(self) wakeup_all(self, errmsg) end end + exit_thread(self) end local function dispatch_function(self) @@ -221,7 +235,7 @@ local function connect_once(self) end self.__sock = setmetatable( {fd} , channel_socket_meta ) - skynet.fork(dispatch_function(self), self) + self.__dispatch_thread = skynet.fork(dispatch_function(self), self) if self.__auth then self.__authcoroutine = coroutine.running() @@ -385,8 +399,13 @@ end function channel:close() if not self.__closed then + local thread = assert(self.__dispatch_thread) self.__closed = true close_channel_socket(self) + if not self.__response and self.__dispatch_thread == thread then + -- dispatch by order, send close signal to dispatch thread + push_response(self, true, false) -- (true, false) is close signal + end end end