about summary refs log tree commit homepage
diff options
context:
space:
mode:
-rw-r--r--lib/mongrel.rb10
-rw-r--r--lib/mongrel/rails.rb21
2 files changed, 26 insertions, 5 deletions
diff --git a/lib/mongrel.rb b/lib/mongrel.rb
index 6fb7222..ca4ea12 100644
--- a/lib/mongrel.rb
+++ b/lib/mongrel.rb
@@ -577,7 +577,10 @@ module Mongrel
             break #done
           else
             # Parser is not done, queue up more data to read and continue parsing
-            data << client.readpartial(Const::CHUNK_SIZE)
+            chunk = client.readpartial(Const::CHUNK_SIZE)
+            break if !chunk or chunk.length == 0  # read failed, stop processing
+
+            data << chunk
             if data.length >= Const::MAX_HEADER
               raise HttpParserError.new("HEADER is longer than allowed, aborting client early.")
             end
@@ -586,8 +589,8 @@ module Mongrel
       rescue EOFError,Errno::ECONNRESET,Errno::EPIPE,Errno::EINVAL,Errno::EBADF
         # ignored
       rescue HttpParserError
-        STDERR.puts "#{Time.now}: BAD CLIENT (#{params[Const::HTTP_X_FORWARDED_FOR] || client.peeraddr.last}): #$!"
         if $mongrel_debug_client
+          STDERR.puts "#{Time.now}: BAD CLIENT (#{params[Const::HTTP_X_FORWARDED_FOR] || client.peeraddr.last}): #$!"
           STDERR.puts "#{Time.now}: REQUEST DATA: #{data.inspect}\n---\nPARAMS: #{params.inspect}\n---\n"
         end
       rescue Errno::EMFILE
@@ -680,6 +683,9 @@ module Mongrel
           rescue Errno::ECONNABORTED
             # client closed the socket even before accept
             client.close rescue Object
+          rescue Object => exc
+            STDERR.puts "!!!!!! UNHANDLED EXCEPTION! #{exc}.  TELL ZED HE'S A MORON."
+            STDERR.puts $!.backtrace.join("\n") if $mongrel_debug_client
           end
         end
 
diff --git a/lib/mongrel/rails.rb b/lib/mongrel/rails.rb
index 3894d2d..c1a7043 100644
--- a/lib/mongrel/rails.rb
+++ b/lib/mongrel/rails.rb
@@ -7,6 +7,11 @@
 require 'mongrel'
 require 'cgi'
 
+class Mutex
+  # modified to open the waiting list for reporting purposes
+  attr_accessor :waiting
+end
+
 module Mongrel
   module Rails
     # Implements a handler that can run Rails and serve files out of the
@@ -37,6 +42,7 @@ module Mongrel
       def initialize(dir, mime_map = {})
         @files = Mongrel::DirHandler.new(dir,false)
         @guard = Mutex.new
+        @tick = Time.now
 
         # register the requested mime types
         mime_map.each {|k,v| Mongrel::DirHandler::add_mime_type(k,v) }
@@ -69,7 +75,7 @@ module Mongrel
             # we don't want the output to be really final until we're out of the lock
             cgi.default_really_final = false
 
-            lock!
+            lock! request.params[Mongrel::Const::PATH_INFO]
 
             Dispatcher.dispatch(cgi, ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS, response.body)
 
@@ -88,20 +94,29 @@ module Mongrel
         end
       end
 
-      def lock!
+      def lock!(path)
         # ultra dangerous, but people are asking to kill themselves.  here's the Katana
+        log_threads_waiting_for path
         @guard.lock unless ActionController::Base.allow_concurrency
       end
 
       def unlock!
+        log_threads_waiting_for "unlock"
         @guard.unlock unless ActionController::Base.allow_concurrency
       end
 
+      def log_threads_waiting_for(event)
+        if $mongrel_debug_client and (Time.now - @tick > 10)
+          STDERR.puts "#{Time.now}: #{@guard.waiting.length} threads waiting for #{event}."
+          @tick = Time.now
+        end
+      end
+
       # Does the internal reload for Rails.  It might work for most cases, but
       # sometimes you get exceptions.  In that case just do a real restart.
       def reload!
         begin
-          lock!
+          lock! "RAILS RELOAD"
           $".replace $orig_dollar_quote
           GC.start
           Dispatcher.reset_application!