Mailing-List: contact cygwin-developers-help AT cygwin DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-developers-owner AT cygwin DOT com Delivered-To: mailing list cygwin-developers AT cygwin DOT com Date: Tue, 18 Feb 2003 17:27:47 -0500 From: Jason Tishler Subject: Threaded socket hang in 1.3.20 To: Cygwin-Developers Mail-followup-to: Cygwin-Developers Message-id: <20030218222746.GD2404@tishler.net> MIME-version: 1.0 Content-type: multipart/mixed; boundary="Boundary_(ID_nZYZUL27H7y0Op07QXv3lA)" User-Agent: Mutt/1.4i --Boundary_(ID_nZYZUL27H7y0Op07QXv3lA) Content-type: text/plain; charset=us-ascii Content-transfer-encoding: 7BIT Content-disposition: inline While running the Python regression test to verify my rebase package before release, I stumbled across a hang in 1.3.20-1 (and CVS) when socket() is called from one thread after accept() has been called in another. This problem has recently been discussed in the following Cygwin mailing thread: http://cygwin.com/ml/cygwin/2003-02/msg01341.html http://cygwin.com/ml/cygwin/2003-02/msg01350.html The problem was introduced sometime after 1.3.19-1 and before 2003-Feb-01 snapshot. The attached C++ testcase demonstrates the problem. In 1.3.20-1, the program hangs in the call to socket() in the second thread: Creating thread for fn1 fn1 begin fn1: calling accept()... Creating thread for fn2 fn2 begin fn2: calling socket()... While in 1.3.19-1, we get the following: Creating thread for fn1 fn1 begin fn1: calling accept()... Creating thread for fn2 fn2 begin fn2: calling socket()... fn2: socket() returned fn2: calling connect()... fn2: connect returned fn2: connect() failed with 111 I'm not sure why connect() fails, because a "telnet localhost 54321" works just fine. I'm probably demonstrating my sockets ignorance. I will try to dig deeper, but I'm hoping that maybe a light bulb will go on in the meantime. BTW, does anyone have any snapshots after 1.3.19-1, but before 2003-Feb-01? If so, please (privately) mail them to me or post a URL. Thanks, Jason -- PGP/GPG Key: http://www.tishler.net/jason/pubkey.asc or key servers Fingerprint: 7A73 1405 7F2B E669 C19D 8784 1AFD E4CC ECF4 8EF6 --Boundary_(ID_nZYZUL27H7y0Op07QXv3lA) Content-type: text/plain; charset=us-ascii; NAME=test_socket.cc Content-transfer-encoding: 7BIT Content-disposition: attachment; filename=test_socket.cc #include #include #include #include #include #include #include #include #include #define PORT 54321 void* fn1(void *id) { printf("fn1 begin\n"); int s = socket(AF_INET, SOCK_STREAM, 0); if (s < 0) { printf("fn1: socket() failed with %d\n", errno); pthread_exit(0); } struct sockaddr_in lsocket; memset(&lsocket, 0, sizeof(lsocket)); lsocket.sin_family = AF_INET; lsocket.sin_addr.s_addr = INADDR_ANY; lsocket.sin_port = htons(PORT); int status = bind(s, (struct sockaddr*) &lsocket, sizeof(lsocket)); if (status < 0) { printf("fn1: bind() failed with %d\n", errno); pthread_exit(0); } status = listen(s, 5); if (status < 0) { printf("fn1: listen() failed with %d\n", errno); pthread_exit(0); } struct sockaddr_in fromAddr; socklen_t fromAddrLen = sizeof(fromAddr); printf("fn1: calling accept()...\n"); status = accept(s, (struct sockaddr*) &fromAddr, &fromAddrLen); printf("fn1: accept returned\n"); printf("fn1 end\n"); pthread_exit(0); } void* fn2(void *id) { printf("fn2 begin\n"); printf("fn2: calling socket()...\n"); int s = socket(AF_INET, SOCK_STREAM, 0); printf("fn2: socket() returned\n"); if (s < 0) { printf("fn1: socket() failed with %d\n", errno); pthread_exit(0); } struct sockaddr_in lsocket; memset(&lsocket, 0, sizeof(lsocket)); lsocket.sin_family = AF_INET; lsocket.sin_addr.s_addr = INADDR_LOOPBACK; lsocket.sin_port = htons(PORT); printf("fn2: calling connect()...\n"); int status = connect(s, (struct sockaddr*) &lsocket, sizeof(lsocket)); printf("fn2: connect returned\n"); if (status < 0) { printf("fn2: connect() failed with %d\n", errno); pthread_exit(0); } printf("fn2 end\n"); pthread_exit(0); } int main(int argc, char *argv[]) { pthread_t thread; printf("Creating thread for fn1\n"); int rc = pthread_create(&thread, 0, fn1, 0); if (rc) { printf("ERROR: return code from pthread_create() is %d\n", rc); exit(-1); } sleep(1); printf("Creating thread for fn2\n"); rc = pthread_create(&thread, 0, fn2, 0); if (rc) { printf("ERROR: return code from pthread_create() is %d\n", rc); exit(-1); } pthread_exit(0); } --Boundary_(ID_nZYZUL27H7y0Op07QXv3lA)--