Details
-
Type:
Bug
-
Status:
Open
-
Priority:
Major
-
Resolution: Unresolved
-
Affects Version/s: JRuby 1.7.0.pre1
-
Fix Version/s: JRuby 1.6.7
-
Component/s: Core Classes/Modules
-
Labels:None
-
Environment:jruby 1.7.0.dev (ruby-1.9.3-p139) (2012-03-31 3ed20a7) (OpenJDK 64-Bit Server VM 1.7.0-u4-b13) [darwin-amd64-java]
-
Number of attachments :
Description
JRuby 1.7-only bug. It's actually fine on 1.6.7.
Repro:
Clone celluloid-io: https://github.com/celluloid/celluloid-io
Bundle
run "rake"
The tests hang around here:
Celluloid::IO::TCPSocket
inside Celluloid::IO
...
It's hanging on a follow-up call to Socket.connect_nonblock. By "follow up", I mean that it's called Socket.connect_nonblock once, gotten Errno::EINPROGRESS, has waited for the given socket to become writable (via nio4r), and is now calling Socket.connect_nonblock again to ensure that the socket is now connected. The code in question looks like this:
begin
@socket.connect_nonblock Socket.sockaddr_in(remote_port, @addr.to_s)
rescue Errno::EINPROGRESS
wait_writable
retry
rescue Errno::EISCONN
# We're now connected! Yay exceptions for flow control
# NOTE: This is the approach the Ruby stdlib docs suggest ;_;
end
Okay, that comment is a bit of a lie, here's the actual example given by the stdlib documentation:
begin # emulate blocking connect
socket.connect_nonblock(sockaddr)
rescue IO::WaitWritable
IO.select(nil, [socket]) # wait 3-way handshake completion
begin
socket.connect_nonblock(sockaddr) # check connection failure
rescue Errno::EISCONN
end
end
My version works fine on both Ruby 1.9.3 and JRuby 1.6.7. However, on JRuby 1.7, connect_nonblock seems to block.