diff --git a/src/box/lua/net_box.lua b/src/box/lua/net_box.lua index 48721f9f08dacfceb25515dad55430111c3cfc8f..e760c67919cb149c55531a8940ec2092a05e5158 100644 --- a/src/box/lua/net_box.lua +++ b/src/box/lua/net_box.lua @@ -598,7 +598,9 @@ local remote_methods = { for _, fid in pairs(list) do if fid ~= fiber.id() then if self.ch.fid[fid] ~= nil then - self.ch.fid[fid]:put(true) + -- timeout=0 prevents deadlock if a client went away + -- without removing the channel + self.ch.fid[fid]:put(true, 0) self.ch.fid[fid] = nil end end @@ -640,6 +642,9 @@ local remote_methods = { return end fiber.sleep(self.opts.reconnect_after) + if self.state == 'closed' then + return + end end self:_switch_state('connecting') diff --git a/test/box/net.box.result b/test/box/net.box.result index 6f0532658d8549157f5ef1b53c2213c4aff08c1a..d843d29d7948a34955bd1694fc5153584ba93f9b 100644 --- a/test/box/net.box.result +++ b/test/box/net.box.result @@ -1016,6 +1016,23 @@ c.space.test:select{} box.space.test:drop() --- ... +-- gh-1904 net.box hangs in :close() if a fiber was cancelled +-- while blocked in :_wait_state() in :_request() +options = {user = 'netbox', password = 'badpass', wait_connected = false, reconnect_after = 0.01} +--- +... +c = net:new(box.cfg.listen, options) +--- +... +f = fiber.create(function() c:call("") end) +--- +... +fiber.sleep(0.1) +--- +... +f:cancel(); c:close() +--- +... box.schema.user.revoke('guest', 'read,write,execute', 'universe') --- ... diff --git a/test/box/net.box.test.lua b/test/box/net.box.test.lua index 02471ad574c63171b89b45a310e392724c65167f..f27146b6d0d82d8a2964f072b0a7a01183946016 100644 --- a/test/box/net.box.test.lua +++ b/test/box/net.box.test.lua @@ -399,5 +399,13 @@ c.space.test:upsert({2, 4, 'nothing'}, {{'+', 3, 100500}}) -- wrong operation c.space.test:select{} box.space.test:drop() +-- gh-1904 net.box hangs in :close() if a fiber was cancelled +-- while blocked in :_wait_state() in :_request() +options = {user = 'netbox', password = 'badpass', wait_connected = false, reconnect_after = 0.01} +c = net:new(box.cfg.listen, options) +f = fiber.create(function() c:call("") end) +fiber.sleep(0.1) +f:cancel(); c:close() + box.schema.user.revoke('guest', 'read,write,execute', 'universe') test_run:cmd("clear filter")