1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* lib/webrick/server.rb: Use a pipe to detect server shutdown.

shutdown() or close() for listening socket is not a reliable.
  Actually, both doesn't work (doesn't wake up select()) on
  DragonFly BSD 3.6.2.

* test/webrick/utils.rb: :ShutdownSocketWithoutClose is not required
  now to immediate server shutdown detection.
  This fixes fd leaks.

* test/net/http/utils.rb: Ditto.



git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@46253 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
akr 2014-05-30 12:32:48 +00:00
parent 99e389a6a7
commit 6f226d9d42
4 changed files with 39 additions and 3 deletions

View file

@ -115,6 +115,7 @@ module WEBrick
@config[:Port] = @listeners[0].addr[1]
end
end
@shutdown_pipe_w = nil
end
##
@ -157,6 +158,9 @@ module WEBrick
raise ServerError, "already started." if @status != :Stop
server_type = @config[:ServerType] || SimpleServer
shutdown_pipe_r, shutdown_pipe_w = IO.pipe
@shutdown_pipe_w = shutdown_pipe_w
server_type.start{
@logger.info \
"#{self.class}#start: pid=#{$$} port=#{@config[:Port]}"
@ -167,7 +171,10 @@ module WEBrick
begin
while @status == :Running
begin
if svrs = IO.select(@listeners, nil, nil, 2.0)
if svrs = IO.select([shutdown_pipe_r, *@listeners], nil, nil, 2.0)
if svrs[0].include? shutdown_pipe_r
return
end
svrs[0].each{|svr|
@tokens.pop # blocks while no token is there.
if sock = accept_client(svr)
@ -193,6 +200,14 @@ module WEBrick
end
ensure
shutdown_pipe_r.close
if !shutdown_pipe_w.closed?
begin
shutdown_pipe_w.close
rescue IOError # Another thread closed shutdown_pipe_w.
end
end
@shutdown_pipe_w = nil
@status = :Shutdown
@logger.info "going to shutdown ..."
thgroup.list.each{|th| th.join if th[:WEBrickThread] }
@ -218,6 +233,16 @@ module WEBrick
def shutdown
stop
shutdown_pipe_w = @shutdown_pipe_w
@shutdown_pipe_w = nil
if shutdown_pipe_w && !shutdown_pipe_w.closed?
begin
shutdown_pipe_w.close
rescue IOError # Another thread closed shutdown_pipe_w.
end
end
@listeners.each{|s|
if @logger.debug?
addr = s.addr