Mail Archives: cygwin/2004/05/05/16:46:52
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 <iostream>
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <string.h>
#include <assert.h>
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<threads; ++i)
{
if(pthread_create(&threadTable[i], NULL, task, (void *)(i+1)) !=
0)
{
cout << "pthread_create() error" << endl;
abort();
}
}
for(int i=0; i<threads; ++i)
{
pthread_join( threadTable[i], NULL );
}
return 0;
}
--- ThreadingTest.cpp -------------------------------------------------
Best regards,
Jacek.
--
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
Problem reports: http://cygwin.com/problems.html
Documentation: http://cygwin.com/docs.html
FAQ: http://cygwin.com/faq/
- Raw text -