summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authordrbrain <drbrain@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-04-11 20:28:11 +0000
committerdrbrain <drbrain@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-04-11 20:28:11 +0000
commit8c5c5a221f3bd3b0bdf6304b924630c35c7f8631 (patch)
tree7081865471aecf1d43b45f47c094be8a36168088 /lib
parent2fe9d4642e4e68538112ea6045cc9a456d7a67b5 (diff)
* lib/webrick/server.rb (module WEBrick::GenericServer): A server
will now continue only when a StandardError subclass is raised. For other exception types the error will be logged at the fatal level and the server will safely stop. Based on a patch by Alex Young. [ruby-trunk - Feature #6236] * test/webrick/test_server.rb: Test for new exception handling behavior. Join the server thread instead of busy-waiting for it to shut down to remove race conditions. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@35303 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib')
-rw-r--r--lib/webrick/server.rb90
1 files changed, 62 insertions, 28 deletions
diff --git a/lib/webrick/server.rb b/lib/webrick/server.rb
index c6d1e4f0f9..22b91ad535 100644
--- a/lib/webrick/server.rb
+++ b/lib/webrick/server.rb
@@ -82,6 +82,27 @@ module WEBrick
@listeners += Utils::create_listeners(address, port, @logger)
end
+ ##
+ # Starts the server and runs the +block+ for each connection. This method
+ # does not return until the server is stopped from a signal handler or
+ # another thread using #stop or #shutdown.
+ #
+ # If the block raises a subclass of StandardError the exception is logged
+ # and ignored. If an IOError or Errno::EBADF exception is raised the
+ # exception is ignored. If an Exception subclass is raised the exception
+ # is logged and re-raised which stops the server.
+ #
+ # To completely shut down a server call #shutdown from ensure:
+ #
+ # server = WEBrick::GenericServer.new
+ # # or WEBrick::HTTPServer.new
+ #
+ # begin
+ # server.start
+ # ensure
+ # server.shutdown
+ # end
+
def start(&block)
raise ServerError, "already started." if @status != :Stop
server_type = @config[:ServerType] || SimpleServer
@@ -93,44 +114,57 @@ module WEBrick
thgroup = ThreadGroup.new
@status = :Running
- while @status == :Running
- begin
- if svrs = IO.select(@listeners, nil, nil, 2.0)
- svrs[0].each{|svr|
- @tokens.pop # blocks while no token is there.
- if sock = accept_client(svr)
- sock.do_not_reverse_lookup = config[:DoNotReverseLookup]
- th = start_thread(sock, &block)
- th[:WEBrickThread] = true
- thgroup.add(th)
- else
- @tokens.push(nil)
- end
- }
+ begin
+ while @status == :Running
+ begin
+ if svrs = IO.select(@listeners, nil, nil, 2.0)
+ svrs[0].each{|svr|
+ @tokens.pop # blocks while no token is there.
+ if sock = accept_client(svr)
+ sock.do_not_reverse_lookup = config[:DoNotReverseLookup]
+ th = start_thread(sock, &block)
+ th[:WEBrickThread] = true
+ thgroup.add(th)
+ else
+ @tokens.push(nil)
+ end
+ }
+ end
+ rescue Errno::EBADF, IOError => ex
+ # if the listening socket was closed in GenericServer#shutdown,
+ # IO::select raise it.
+ rescue StandardError => ex
+ msg = "#{ex.class}: #{ex.message}\n\t#{ex.backtrace[0]}"
+ @logger.error msg
+ rescue Exception => ex
+ @logger.fatal ex
+ raise
end
- rescue Errno::EBADF, IOError => ex
- # if the listening socket was closed in GenericServer#shutdown,
- # IO::select raise it.
- rescue Exception => ex
- msg = "#{ex.class}: #{ex.message}\n\t#{ex.backtrace[0]}"
- @logger.error msg
end
- end
- @logger.info "going to shutdown ..."
- thgroup.list.each{|th| th.join if th[:WEBrickThread] }
- call_callback(:StopCallback)
- @logger.info "#{self.class}#start done."
- @status = :Stop
+ ensure
+ @logger.info "going to shutdown ..."
+ thgroup.list.each{|th| th.join if th[:WEBrickThread] }
+ call_callback(:StopCallback)
+ @logger.info "#{self.class}#start done."
+ @status = :Stop
+ end
}
end
+ ##
+ # Stops the server from accepting new connections.
+
def stop
if @status == :Running
- @status = :Shutdown
+ @status = :Stop
end
end
+ ##
+ # Shuts down the server and all listening sockets. New listeners must be
+ # provided to restart the server.
+
def shutdown
stop
@listeners.each{|s|
@@ -169,7 +203,7 @@ module WEBrick
Utils::set_close_on_exec(sock)
rescue Errno::ECONNRESET, Errno::ECONNABORTED,
Errno::EPROTO, Errno::EINVAL => ex
- rescue Exception => ex
+ rescue StandardError => ex
msg = "#{ex.class}: #{ex.message}\n\t#{ex.backtrace[0]}"
@logger.error msg
end