about summary refs log tree commit homepage
path: root/lib/rainbows/coolio
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2011-03-10 15:06:10 -0800
committerEric Wong <normalperson@yhbt.net>2011-03-10 15:06:10 -0800
commitcd8a874d18fe01e11bb57b91186b6c9f712a4b3f (patch)
treea8400f2e6eeca1a4d4a686e138b97eb831eb9a8d /lib/rainbows/coolio
parentafea5cd7c691de95b37d29728ab4880e3b737a42 (diff)
downloadrainbows-cd8a874d18fe01e11bb57b91186b6c9f712a4b3f.tar.gz
IO#trysendfile does not raise exceptions for common EAGAIN
errors, making it far less expensive to use with the following
concurrency models:

* Coolio
* CoolioFiberSpawn
* Revactor
* FiberSpawn
* FiberPool

This requires the new sendfile 1.1.0 RubyGem and removes support
for the sendfile 1.0.0.  All sendfile users must upgrade or be
left without sendfile(2) support.  IO#sendfile behaves the same
if you're using a multi-threaded concurrency option, but we
don't detect nor use it unless IO#trysendfile exists.
Diffstat (limited to 'lib/rainbows/coolio')
-rw-r--r--lib/rainbows/coolio/client.rb25
1 files changed, 13 insertions, 12 deletions
diff --git a/lib/rainbows/coolio/client.rb b/lib/rainbows/coolio/client.rb
index 9853321..2de421a 100644
--- a/lib/rainbows/coolio/client.rb
+++ b/lib/rainbows/coolio/client.rb
@@ -125,11 +125,8 @@ class Rainbows::Coolio::Client < Coolio::IO
     when true then return # #next! will clear this bit
     when nil # fall through
     else
-      begin
-        return stream_file_chunk(@deferred)
-      rescue EOFError # expected at file EOF
-        close_deferred # fall through
-      end
+      return if stream_file_chunk(@deferred)
+      close_deferred # EOF, fall through
     end
 
     case @state
@@ -179,7 +176,7 @@ class Rainbows::Coolio::Client < Coolio::IO
     KATO.delete(self)
   end
 
-  if IO.method_defined?(:sendfile_nonblock)
+  if IO.method_defined?(:trysendfile)
     def defer_file(status, headers, body, alive, io, st)
       if r = sendfile_range(status, headers)
         status, headers, range = r
@@ -192,11 +189,15 @@ class Rainbows::Coolio::Client < Coolio::IO
     end
 
     def stream_file_chunk(sf) # +sf+ is a Rainbows::StreamFile object
-      sf.offset += (n = @_io.sendfile_nonblock(sf, sf.offset, sf.count))
-      0 == (sf.count -= n) and raise EOFError
-      enable_write_watcher
-      rescue Errno::EAGAIN
-        enable_write_watcher
+      case n = @_io.trysendfile(sf, sf.offset, sf.count)
+      when Integer
+        sf.offset += n
+        return if 0 == (sf.count -= n)
+      when :wait_writable
+        return enable_write_watcher
+      else
+        return
+      end while true
     end
   else
     def defer_file(status, headers, body, alive, io, st)
@@ -205,7 +206,7 @@ class Rainbows::Coolio::Client < Coolio::IO
     end
 
     def stream_file_chunk(body)
-      write(body.to_io.sysread(0x4000))
+      buf = body.to_io.read(0x4000) and write(buf)
     end
   end