diff options
-rw-r--r-- | lib/mogilefs/socket/pure_ruby.rb | 87 |
1 files changed, 60 insertions, 27 deletions
diff --git a/lib/mogilefs/socket/pure_ruby.rb b/lib/mogilefs/socket/pure_ruby.rb index e74bbef..d57a7c0 100644 --- a/lib/mogilefs/socket/pure_ruby.rb +++ b/lib/mogilefs/socket/pure_ruby.rb @@ -27,16 +27,6 @@ class MogileFS::Socket < Socket IO.select(nil, [ self ], nil, timeout) end unless self.instance_methods.include?(:wait_writable) # Ruby <2.0.0 - def timed_read(len, dst = "", timeout = 5) - begin - return read_nonblock(len, dst) - rescue Errno::EAGAIN - wait(timeout) or unreadable_socket!(timeout) - rescue EOFError - return - end while true - end - def timed_peek(len, dst, timeout = 5) begin rc = recv_nonblock(len, Socket::MSG_PEEK) @@ -47,26 +37,69 @@ class MogileFS::Socket < Socket dst.replace("") return end while true + rescue EOFError + nil end - def timed_write(buf, timeout = 5) - written = 0 - expect = buf.bytesize - begin - rc = write_nonblock(buf) - return expect if rc == buf.bytesize - written += rc + # write_nonblock and read_nonblock support `exception: false` + if RUBY_VERSION.to_f >= 2.1 + def timed_read(len, dst = "", timeout = 5) + case rc = read_nonblock(len, dst, :exception => false) + when String + return rc + when :wait_readable + wait(timeout) or unreadable_socket!(timeout) + when nil + return + end while true + rescue EOFError + nil + end + + def timed_write(buf, timeout = 5) + written = 0 + expect = buf.bytesize + case rc = write_nonblock(buf, :exception => false) + when Integer + return expect if rc == buf.bytesize + written += rc + buf = buf.byteslice(rc, buf.bytesize) # Ruby 1.9.3+ + when :wait_writable + wait_writable(timeout) or request_truncated!(written, expect, timeout) + end while true + end + else # Ruby 1.8.7 - 2.0.0 + def timed_read(len, dst = "", timeout = 5) + begin + return read_nonblock(len, dst) + rescue Errno::EAGAIN + wait(timeout) or unreadable_socket!(timeout) + rescue EOFError + return + end while true + rescue EOFError + nil + end - if buf.respond_to?(:byteslice) - buf = buf.byteslice(rc, buf.bytesize) - else - if buf.respond_to?(:encoding) && buf.encoding != Encoding::BINARY - buf = buf.dup.force_encoding(Encoding::BINARY) + def timed_write(buf, timeout = 5) + written = 0 + expect = buf.bytesize + begin + rc = write_nonblock(buf) + return expect if rc == buf.bytesize + written += rc + + if buf.respond_to?(:byteslice) # Ruby 1.9.3+ + buf = buf.byteslice(rc, buf.bytesize) + else + if buf.respond_to?(:encoding) && buf.encoding != Encoding::BINARY + buf = buf.dup.force_encoding(Encoding::BINARY) + end + buf = buf.slice(rc, buf.bytesize) end - buf = buf.slice(rc, buf.bytesize) - end - rescue Errno::EAGAIN - wait_writable(timeout) or request_truncated!(written, expect, timeout) - end while true + rescue Errno::EAGAIN + wait_writable(timeout) or request_truncated!(written, expect, timeout) + end while true + end end end |