diff options
author | Eric Wong <e@80x24.org> | 2015-12-13 12:19:00 +0000 |
---|---|---|
committer | Eric Wong <e@80x24.org> | 2015-12-13 12:29:43 +0000 |
commit | d3cf61b05d9507e7b6ea5a1a1192e107a8612049 (patch) | |
tree | 7e150cbc3177d58941aa3f26017627ac006b13aa /lib/dtas/buffer | |
parent | e751a396e43f07f15d9b639a850c0c8cbebf9539 (diff) | |
download | dtas-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')
-rw-r--r-- | lib/dtas/buffer/read_write.rb | 40 |
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 |