about summary refs log tree commit homepage
path: root/lib/dtas/buffer/read_write.rb
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2015-12-13 12:19:00 +0000
committerEric Wong <e@80x24.org>2015-12-13 12:29:43 +0000
commitd3cf61b05d9507e7b6ea5a1a1192e107a8612049 (patch)
tree7e150cbc3177d58941aa3f26017627ac006b13aa /lib/dtas/buffer/read_write.rb
parente751a396e43f07f15d9b639a850c0c8cbebf9539 (diff)
downloaddtas-d3cf61b05d9507e7b6ea5a1a1192e107a8612049.tar.gz
Ruby 2.3 will have `exception: false' support in socket-related
classes.  Additionally, 2.3 will implement the existing
IO#*_nonblock methods more efficiently than before by avoiding
the hash allocation necessary for keywords.

For users on older Rubies, we'll continue supporting them with
compatibility wrappers; even Ruby 1.9.3 users (for now).
Diffstat (limited to 'lib/dtas/buffer/read_write.rb')
-rw-r--r--lib/dtas/buffer/read_write.rb40
1 files changed, 21 insertions, 19 deletions
diff --git a/lib/dtas/buffer/read_write.rb b/lib/dtas/buffer/read_write.rb
index 64ad297..76c60b0 100644
--- a/lib/dtas/buffer/read_write.rb
+++ b/lib/dtas/buffer/read_write.rb
@@ -3,6 +3,7 @@
 require 'io/nonblock'
 require_relative '../../dtas'
 require_relative '../pipe'
+require_relative '../nonblock'
 
 # compatibility code for systems lacking "splice" support via the
 # "io-splice" RubyGem.  Used only by -player
@@ -28,14 +29,12 @@ module DTAS::Buffer::ReadWrite # :nodoc:
   # always block when we have a single target
   def broadcast_one(targets, limit = nil)
     buf = _rbuf
-    @to_io.read_nonblock(limit || MAX_AT_ONCE, buf)
+    case rv = @to_io.read_nonblock(limit || MAX_AT_ONCE, buf, exception: false)
+    when nil, :wait_readable then return rv
+    end
     n = targets[0].write(buf) # IO#write has write-in-full behavior
     @bytes_xfer += n
     :wait_readable
-  rescue EOFError
-    nil
-  rescue Errno::EAGAIN
-    :wait_readable
   rescue Errno::EPIPE, IOError => e
     __dst_error(targets[0], e)
     targets.clear
@@ -71,15 +70,16 @@ module DTAS::Buffer::ReadWrite # :nodoc:
     targets.delete_if do |dst|
       begin
         if dst.nonblock?
-          w = dst.write_nonblock(buf)
-          again[dst] = buf.byteslice(w, n) if w < n
+          case w = dst.write_nonblock(buf, exception: false)
+          when :wait_writable
+            blocked << dst
+          else
+            again[dst] = buf.byteslice(w, n) if w < n
+          end
         else
           dst.write(buf)
         end
         false
-      rescue Errno::EAGAIN
-        blocked << dst
-        false
       rescue IOError, Errno::EPIPE => e
         again.delete(dst)
         __dst_error(dst, e)
@@ -90,17 +90,19 @@ module DTAS::Buffer::ReadWrite # :nodoc:
     # try to write as much as possible
     again.delete_if do |dst, sbuf|
       begin
-        w = dst.write_nonblock(sbuf)
-        n = sbuf.bytesize
-        if w < n
-          again[dst] = sbuf.byteslice(w, n)
-          false
-        else
+        case w = dst.write_nonblock(sbuf, exception: false)
+        when :wait_writable
+          blocked << dst
           true
+        else
+          n = sbuf.bytesize
+          if w < n
+            again[dst] = sbuf.byteslice(w, n)
+            false
+          else
+            true
+          end
         end
-      rescue Errno::EAGAIN
-        blocked << dst
-        true
       rescue IOError, Errno::EPIPE => e
         __dst_error(dst, e)
         true