Ruby 1.8.7. I'm calling read on a socket which has been opened and connected with:
socket = Socket.new(AF_INET, SOCK_STREAM, 0)
sockaddr = Socket.sockaddr_in(mp.port, mp.ip_address.ip)
begin
socket.connect_nonblock(sockaddr)
[...]
The connection is confirmed by calling select() and then connecting a second time looking for Errno::EISCONN.
I then call select again with a 0 timeout and if the return is not nil I read from the socket, first confirming that it has O_NONBLOCK set:
rc = select([socket], nil, nil, 0)
puts " select returned: #{rc.pretty_inspect}"
if rc
begin
puts " reading: #{socket} nonblock: #{socket.fcntl(Fcntl::F_GETFL) & Fcntl::O_NONBLOCK}"
response = socket.read
puts " done reading"
[...]
This all happens in a loop once per minute. The output the first time through the loop is:
select returned: [[#<Socket:0xb6e0dcb8>], [], []]
reading: #<Socket:0xb6e0dcb8> nonblock: 2048
done reading
However the second time through the loop hangs here:
select returned: [[#<Socket:0xb6e0dcb8>], [], []]
reading: #<Socket:0xb6e0dcb8> nonblock: 2048
Attaching gdb to the process shows this backtrace:
0 0xffffe410 in __kernel_vsyscall ()
1 0xb7e5539d in select () from /lib/tls/i686/cmov/libc.so.6
2 0x08064368 in rb_thread_schedule () at eval.c:11020
3 0x080785bb in io_fread (
Replacing the call to read with a call to rcvfrom_nonblock works, and interestingly it does not get EAGAIN, it actually reads data (as you would expect given the return from select).
Any ideas?
steve