Skip to content

Commit

Permalink
socket: fix error while closing socket.tcp_server
Browse files Browse the repository at this point in the history
The tcp server starts in a separate fiber.
When server's socket is closed from another fiber,
an exception will be thrown in server's loop from
check_socket function.
A "socket is close" check has been added at server's
fiber and now server's fiber terminates correctly.

Fixes: #4087
  • Loading branch information
LeonidVas authored and kyukhin committed Jun 2, 2020
1 parent c84a853 commit a70675e
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 4 deletions.
14 changes: 11 additions & 3 deletions src/lua/socket.lua
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,17 @@ local gc_socket_t = ffi.metatype(ffi.typeof('struct gc_socket'), {

local socket_mt

local function socket_is_closed(socket)
-- The type of 'socket' is not checked because the function
-- is internal and the type must be checked outside if needed.
return socket._gc_socket.fd < 0
end

local function check_socket(socket)
local gc_socket = type(socket) == 'table' and socket._gc_socket
if ffi.istype(gc_socket_t, gc_socket) then
local fd = gc_socket.fd
if fd >= 0 then
return fd
if not socket_is_closed(socket) then
return gc_socket.fd
else
error("attempt to use closed socket")
end
Expand Down Expand Up @@ -1082,6 +1087,9 @@ local function tcp_server_loop(server, s, addr)
fiber.name(format("%s/%s:%s", server.name, addr.host, addr.port), {truncate = true})
log.info("started")
while socket_readable(s) do
if socket_is_closed(s) then
break
end
local sc, from = socket_accept(s)
if sc == nil then
local errno = s._errno
Expand Down
14 changes: 14 additions & 0 deletions test/app/socket.result
Original file line number Diff line number Diff line change
Expand Up @@ -2914,3 +2914,17 @@ srv:close()
---
- true
...
--
-- gh-4087: fix error while closing socket.tcp_server
--
srv = socket.tcp_server('127.0.0.1', 0, function() end)
---
...
srv:close()
---
- true
...
test_run:wait_log('default', 'stopped', 1024, 0.01)
---
- stopped
...
7 changes: 6 additions & 1 deletion test/app/socket.test.lua
Original file line number Diff line number Diff line change
Expand Up @@ -987,4 +987,9 @@ s:settimeout(1)
s:receive('*a')
s:close()
srv:close()

--
-- gh-4087: fix error while closing socket.tcp_server
--
srv = socket.tcp_server('127.0.0.1', 0, function() end)
srv:close()
test_run:wait_log('default', 'stopped', 1024, 0.01)

0 comments on commit a70675e

Please sign in to comment.