This is the mail archive of the cygwin mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: pthreads and sockets - Cannot register window class error


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/


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]