From e5bd756d0a8ab73cab16facbd6f1b2275f6dfa21 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Fri, 18 Jun 2010 08:59:01 +0000 Subject: rev: avoid extraneous data copy for small responses 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. --- lib/rainbows/rev/client.rb | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) 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 -- cgit v1.2.3-24-ge0c7