« Return to Thread: socket woes

Re: Re: socket woes

by Ivan Warren :: Rate this Message:

Reply to Author | View in Thread

Paul,

First, the correction to create_pipe/socketpair is correct (the 2nd &
3rd parameters are reversed).... But irrelevant to your problem !

The parameters are NOT actually used besides to check for validity.

I believe your problem is a race condition.

On Windows, it seems we took the route to use TCP sockets to emulate the
BSD 'socketpair' system call (I don't know why we didn't go for named
pipes, but this might not have been available on Win9X).

Anyway, the way it's done is this :

A socket of type AF_INET/SOCK_STREAM is created, bound to 127.0.0.1 port
0 and put into listen
A connect is issued to 127.0.0.1 port 0
An Accept is issued to grab the other side
The listening socket is closed.

On a Posix system, doing this would lead to a EADDRINUSE on the 2nd try
unless you do a setsockopt/SOCK_REUSE_ADDR.. Windows seems to not have
this problem. We don't have that problem on linux because under linux
socketpair() does not involves binding sockets for listening.

However, if multiple threads attempt to simultaneously call the
socketpair function in w32util.c, there is a time window for one or more
of simultaneous attempts to fail if the 1st attempt hasn't completed its
work. Apparently, I'd say a lock is in order here to serialize access to
w32util.c[socketpair()].

In hercules, you have a good chance of this happening if the
connect/accept sequence is taking an unusual amount of time to complete
(a firewall may cause this for example).

The 3270 shoulder tap socket and the console logging pipes are created
consecutively in the same thread.. So they can't be directly
responsible.. (or rather it's not those 2 conflicting).. But the printer
emulation code and the BSC emulation code may be doing those in separate
threads..

Anyway.. Could you try this :
===================================================================
--- w32util.c   (revision 5421)
+++ w32util.c   (working copy)
@@ -1881,6 +1881,7 @@
     localhost_addr.sin_port         = htons( 0 );
     localhost_addr.sin_addr.s_addr  = htonl( INADDR_LOOPBACK );

+    obtain_lock(&sysblk.sockpipe_lock);
     if (0
         || SOCKET_ERROR   == bind( temp_listen_socket, (SOCKADDR*)
&localhost_addr, len )
         || SOCKET_ERROR   == listen( temp_listen_socket, 1 )
@@ -1890,6 +1891,7 @@
     {
         int nLastError = (int)WSAGetLastError();
         closesocket( temp_listen_socket );
+        release_lock(&sysblk.sockpipe_lock);
         errno = nLastError;
         return -1;
     }
@@ -1903,11 +1905,13 @@
         closesocket( socket_vector[1] );
                      socket_vector[1] = INVALID_SOCKET;
         closesocket( temp_listen_socket );
+        release_lock(&sysblk.sockpipe_lock);
         errno = nLastError;
         return -1;
     }

     closesocket( temp_listen_socket );
+    release_lock(&sysblk.sockpipe_lock);
     return 0;
 }




[Non-text portions of this message have been removed]

 « Return to Thread: socket woes