Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com Delivered-To: mailing list cygwin AT cygwin DOT com Message-ID: <409952A3.41858179@hot.pl> Date: Wed, 05 May 2004 22:46:27 +0200 From: Jacek Trzmiel MIME-Version: 1.0 To: cygwin AT cygwin DOT com Subject: Re: pthreads and sockets - Cannot register window class error References: <4098760F DOT CDB4F630 AT hot DOT pl> <4098E04B DOT 34D2866B AT dessent DOT net> Content-Type: text/plain; charset=iso-8859-2 Content-Transfer-Encoding: 7bit X-IsSubscribed: yes Hi Brian, > > void test() > > { > > /* go find out about the desired host machine */ > > struct hostent *he = gethostbyname(HOST); > > if (he == 0) { > > perror("gethostbyname"); > > exit(1); > > } > > Just a wild guess, but gethostbyname() is probably not reentrant and > can't be called from threads like that. Thanks, it may be: http://www.opengroup.org/onlinepubs/009695399/functions/gethostbyaddr.html "The gethostbyname() function need not be reentrant. A function that is not required to be reentrant is not required to be thread-safe." This can explain those errors: gethostbynamegethostbyname: Operation not permitted However "Winmain: Cannot register window class, Win32 error 1410" still happens with modified code: --- ThreadingTest.cpp ------------------------------------------------- #include #include #include #include #include #include #include #include #include #include #include using std::cout; using std::endl; const char *HOST = "example.org"; const int PORT = 80; const char *MESSAGE = "GET / HTTP/1.0\r\n\r\n"; struct hostent *g_he = 0; void sendall( int sd, const char *data, int datalen ) { assert( data ); assert( datalen >= 0 ); while(datalen>0) { int sent = send(sd, data, datalen, 0); if( sent == -1) { perror("send"); exit(1); } data += sent; datalen -= sent; assert( datalen>=0 ); } } void recvandprintall( int sd ) { const int bufferlen = 65536; char buffer[bufferlen]; while(true) { int got = recv(sd, buffer, bufferlen, 0); if(got == -1) { perror("recv"); exit(1); } if(got==0) { cout << "got\n"; cout.flush(); break; } } } void test() { /* fill in the socket structure with host information */ struct sockaddr_in pin; memset( &pin, 0, sizeof(pin) ); pin.sin_family = AF_INET; pin.sin_addr.s_addr = ((struct in_addr *)(g_he->h_addr))->s_addr; pin.sin_port = htons(PORT); /* grab an Internet domain socket */ int sd; if ((sd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("socket"); exit(1); } /* connect to PORT on HOST */ if (connect(sd,(struct sockaddr *) &pin, sizeof(pin)) == -1) { perror("connect"); exit(1); } /* send a message to the server PORT on machine HOST */ sendall( sd, MESSAGE, strlen(MESSAGE) ); /* shutdown writing part of socket */ shutdown( sd, SHUT_WR ); /* wait for data to come back from the server and print it */ recvandprintall( sd ); close(sd); } void *task(void *arg) { test(); return NULL; } int main() { /* go find out about the desired host machine */ g_he = gethostbyname(HOST); if(g_he == 0) { perror("gethostbyname"); exit(1); } assert( g_he->h_addrtype == AF_INET ); assert( g_he->h_addr_list[0] ); const int threads = 70; pthread_t threadTable[threads]; for(int i=0; i