about summary refs log tree commit homepage
path: root/lib
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2010-06-18 08:59:01 +0000
committerEric Wong <normalperson@yhbt.net>2010-06-18 08:59:01 +0000
commite5bd756d0a8ab73cab16facbd6f1b2275f6dfa21 (patch)
tree54f301c351c68376020b21fdc457da5db954eb2c /lib
parentb290a65eb735aa89bb071e27f8421cc864c78e8c (diff)
downloadrainbows-e5bd756d0a8ab73cab16facbd6f1b2275f6dfa21.tar.gz
For small responses that can fit inside a kernel socket
buffer, copying that data into an IO::Buffer object is
a waste of precious memory bandwidth.
Diffstat (limited to 'lib')
-rw-r--r--lib/rainbows/rev/client.rb27
1 files changed, 27 insertions, 0 deletions
diff --git a/lib/rainbows/rev/client.rb b/lib/rainbows/rev/client.rb
index 2b2bd45..788d8c8 100644
--- a/lib/rainbows/rev/client.rb
+++ b/lib/rainbows/rev/client.rb
@@ -14,6 +14,33 @@ module Rainbows
         @deferred_bodies = [] # for (fast) regular files only
       end
 
+      def quit
+        super
+        close if @deferred_bodies.empty? && @_write_buffer.empty?
+      end
+
+      def write(buf)
+        if @_write_buffer.empty?
+          rv = buf.size
+          # try to write directly to the kernel socket buffers to avoid an
+          # extra userspace copy if possible.
+          begin
+            w = @_io.write_nonblock(buf)
+            if w == buf.size
+              on_write_complete
+              return rv
+            end
+            buf = buf[w..-1]
+          rescue Errno::EAGAIN
+            break # copy what's left into the IO::Buffer
+          rescue
+            close
+            return
+          end while true
+        end
+        super(buf)
+      end
+
       # queued, optional response bodies, it should only be unpollable "fast"
       # devices where read(2) is uninterruptable.  Unfortunately, NFS and ilk
       # are also part of this.  We'll also stick DeferredResponse bodies in