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