Mail Archives: cygwin-developers/2003/02/18/17:20:24
--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 <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/errno.h>
#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)--
- Raw text -