1 # -*- encoding: binary -*-
2 # internal implementation details here, do not rely on them in your code
5 class MogileFS::Socket < Socket
6 include MogileFS::SocketCommon
8 if RUBY_VERSION.to_f >= 2.3
9 def self.start(host, port)
10 sock = new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
11 sock.connect_nonblock(sockaddr_in(port, host), :exception => false)
12 sock.post_init(host, port)
15 def self.start(host, port)
16 sock = new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
18 sock.connect_nonblock(sockaddr_in(port, host))
19 rescue Errno::EINPROGRESS
21 sock.post_init(host, port)
25 def self.tcp(host, port, timeout = 5)
26 sock = start(host, port)
27 unless sock.wait_writable(timeout)
29 raise MogileFS::Timeout, 'socket connect timeout'
34 def wait_writable(timeout = nil)
35 IO.select(nil, [ self ], nil, timeout)
36 end unless self.instance_methods.include?(:wait_writable) # Ruby <2.0.0
38 def timed_peek(len, dst, timeout = 5)
40 rc = recv_nonblock(len, Socket::MSG_PEEK)
41 return rc.empty? ? nil : dst.replace(rc)
43 wait(timeout) or unreadable_socket!(timeout)
52 # write_nonblock and read_nonblock support `exception: false`
53 if RUBY_VERSION.to_f >= 2.1
54 def timed_read(len, dst = "", timeout = 5)
55 case rc = read_nonblock(len, dst, :exception => false)
59 wait(timeout) or unreadable_socket!(timeout)
67 def timed_write(buf, timeout = 5)
70 case rc = write_nonblock(buf, :exception => false)
72 return expect if rc == buf.bytesize
74 buf = buf.byteslice(rc, buf.bytesize) # Ruby 1.9.3+
76 wait_writable(timeout) or request_truncated!(written, expect, timeout)
79 else # Ruby 1.8.7 - 2.0.0
80 def timed_read(len, dst = "", timeout = 5)
82 return read_nonblock(len, dst)
84 wait(timeout) or unreadable_socket!(timeout)
92 def timed_write(buf, timeout = 5)
96 rc = write_nonblock(buf)
97 return expect if rc == buf.bytesize
100 if buf.respond_to?(:byteslice) # Ruby 1.9.3+
101 buf = buf.byteslice(rc, buf.bytesize)
103 if buf.respond_to?(:encoding) && buf.encoding != Encoding::BINARY
104 buf = buf.dup.force_encoding(Encoding::BINARY)
106 buf = buf.slice(rc, buf.bytesize)
109 wait_writable(timeout) or request_truncated!(written, expect, timeout)