Issue #9356 has been updated by Eric Wong.


 shugo / ruby-lang.org wrote:
 > Eric Wong wrote:
 > >  OK.  I wonder if we should even use getsockopt(SO_ERROR) at all.
 > >  
 > >  I know there's much literature which recommends it, but any error check
 > >  in this way is racy.  Better to let any subsequent
 > >  write/read/send/recv/etc error out.
 > 
 > Could you describe such a race condition in detail?
 
 	getsockopt(SO_ERROR) => no error
 	<kernel sees disconnect>
 	read/write => EPIPE, ENOTCONN, ...
 
 Since we must check all (future) read/write operations for errors
 anyways, getsockopt(SO_ERROR) is worthless.
 
 > I don't see a race condition on FreeBSD 10.
 > 
 > The problem I've seen is that rb_wait_for_single_fd() returns RB_WAITFD_OUT, and getsockopt() with SO_ERROR doesn't return any error (this is an expected behavior when the socket is connected), and Ruby goes in an infinite loop.
 > 
 > This problem was introduced by r31424, and usa is not guilty at least for the problem I've seen.
 > 
 > How about to fix the code as follows?
 > 
 >             if (sockerr == 0) {
 >                 if (revents & RB_WAITFD_OUT) {
 >                     break;
 >                 }
 >                 else {
 >                     continue;       /* control is reached here on winsock? */
 >                 }
 >             }
 
 Maybe, but I wonder if we can just drop a lot of code...
 
 	http://bogomips.org/ruby.git/patch?id=a4212dc9516f4

----------------------------------------
Bug #9356: TCPSocket.new does not seem to handle INTR
https://bugs.ruby-lang.org/issues/9356#change-45274

* Author: Charlie Somerville
* Status: Open
* Priority: Normal
* Assignee: 
* Category: 
* Target version: 
* ruby -v: -
* Backport: 1.9.3: UNKNOWN, 2.0.0: UNKNOWN, 2.1: UNKNOWN
----------------------------------------
TCPSocket.new does not seem to handle EINTR properly.

In the attached test script, I try to open a TCP connection to my server and make an HTTP request while a background thread continually sends a signal to the process.

This causes the #write call to fail with:

x.rb:13:in `write': Socket is not connected (Errno::ENOTCONN)
	from x.rb:13:in `<main>'

This also appears to affect 2.0.0. 1.9.3 is unaffected.

---Files--------------------------------
socket-eintr.rb (207 Bytes)


-- 
http://bugs.ruby-lang.org/