[前][次][番号順一覧][スレッド一覧]

ruby-changes:34172

From: akr <ko1@a...>
Date: Fri, 30 May 2014 21:32:57 +0900 (JST)
Subject: [ruby-changes:34172] akr:r46253 (trunk): * lib/webrick/server.rb: Use a pipe to detect server shutdown.

akr	2014-05-30 21:32:48 +0900 (Fri, 30 May 2014)

  New Revision: 46253

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?revision=46253&view=revision

  Log:
    * 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.

  Modified files:
    trunk/ChangeLog
    trunk/lib/webrick/server.rb
    trunk/test/net/http/utils.rb
    trunk/test/webrick/utils.rb
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 46252)
+++ ChangeLog	(revision 46253)
@@ -1,3 +1,16 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Fri May 30 21:23:26 2014  Tanaka Akira  <akr@f...>
+
+	* 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.
+
 Fri May 30 20:58:37 2014  Tanaka Akira  <akr@f...>
 
 	* test/lib/minitest/unit.rb (check_fd_leak): Sort the inspected
Index: lib/webrick/server.rb
===================================================================
--- lib/webrick/server.rb	(revision 46252)
+++ lib/webrick/server.rb	(revision 46253)
@@ -115,6 +115,7 @@ module WEBrick https://github.com/ruby/ruby/blob/trunk/lib/webrick/server.rb#L115
           @config[:Port] = @listeners[0].addr[1]
         end
       end
+      @shutdown_pipe_w = nil
     end
 
     ##
@@ -157,6 +158,9 @@ module WEBrick https://github.com/ruby/ruby/blob/trunk/lib/webrick/server.rb#L158
       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 https://github.com/ruby/ruby/blob/trunk/lib/webrick/server.rb#L171
         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 https://github.com/ruby/ruby/blob/trunk/lib/webrick/server.rb#L200
           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 https://github.com/ruby/ruby/blob/trunk/lib/webrick/server.rb#L233
 
     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
Index: test/webrick/utils.rb
===================================================================
--- test/webrick/utils.rb	(revision 46252)
+++ test/webrick/utils.rb	(revision 46253)
@@ -37,7 +37,6 @@ module TestWEBrick https://github.com/ruby/ruby/blob/trunk/test/webrick/utils.rb#L37
     log = proc { "webrick log start:\n" + log_string.gsub(/^/, "  ").chomp + "\nwebrick log end" }
     server = klass.new({
       :BindAddress => "127.0.0.1", :Port => 0,
-      :ShutdownSocketWithoutClose =>true,
       :ServerType => Thread,
       :Logger => WEBrick::Log.new(logger),
       :AccessLog => [[logger, ""]]
Index: test/net/http/utils.rb
===================================================================
--- test/net/http/utils.rb	(revision 46252)
+++ test/net/http/utils.rb	(revision 46253)
@@ -49,7 +49,6 @@ module TestNetHTTPUtils https://github.com/ruby/ruby/blob/trunk/test/net/http/utils.rb#L49
       :Port => 0,
       :Logger => WEBrick::Log.new(NullWriter.new),
       :AccessLog => [],
-      :ShutdownSocketWithoutClose => true,
       :ServerType => Thread,
     }
     server_config[:OutputBufferSize] = 4 if config('chunked')

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]