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]

pthreads and sockets - Cannot register window class error


Hi again,

I have problem using pthreads together with sockets on cygwin 1.5.9-1,
win2k sp4.

Here is minimal app where I can reproduce errors.  It will start 70
threads and fetch http://example.org/ page on every each of them. 
Please change host on line:
    const char *HOST = "example.org";
if you don't want to DDOS it ;)

--- 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";


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()
{
    /* go find out about the desired host machine */
    struct hostent *he = gethostbyname(HOST);
    if (he == 0) {
        perror("gethostbyname");
        exit(1);
    }
    assert( he->h_addrtype == AF_INET );
    assert( he->h_addr_list[0] );

    /* 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 *)(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()
{
    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 -------------------------------------------------


Compile and run it this way:

> $ g++ ThreadingTest.cpp -lpthread -o ThreadingTest.exe && ./ThreadingTest.exe
> got
> got
> got
[...]

If everything goes right, then it prints "got" 70 times and quits. 


However sometimes it fails this way (you may need to run it several
times to reproduce error):

> $ g++ ThreadingTest.cpp -lpthread -o ThreadingTest.exe && ./ThreadingTest.exe
>     285 [win] ThreadingTest 1476 Winmain: Cannot register window class, Win32 error 1410
>     305 [win] ThreadingTest 1476 Winmain: Cannot register window class, Win32 error 1410
>    1998 [win] ThreadingTest 1476 Winmain: Cannot register window class, Win32 error 1410
> D:\Sources\Test\ThreadingTest.exe (2040): *** WFSO failed, Win32 error 6
>     312 [win] ThreadingTest 1476 Winmain: Cannot register window class, Win32 error 1410
> got


I've seen also this problem:
> $ g++ ThreadingTest.cpp -o ThreadingTest.exe && ./ThreadingTest.exe
> gethostbynamegethostbyname: Operation not permitted

(BTW. Is -lpthread necessary?  It does link without it.  Is it implied?)


I've googled on this and found thread with similar problem, no solution
though:

http://groups.google.com/groups?lr=&ie=UTF-8&threadm=b840abf4.0401221419.343cb5e1%40posting.google.com&rnum=1&prev=/groups%3Fq%3Dpython%2BCannot%2Bregister%2Bwindow%2Bclass%26hl%3Dpl%26lr%3D%26ie%3DUTF-8%26oe%26inlang%3Dpl%26selm%3Db840abf4.0401221419.343cb5e1%2540posting.google.com%26rnum%3D1
http://www.cygwin.com/ml/cygwin/2004-01/msg01371.html
http://www.cygwin.com/ml/cygwin/2004-02/msg00101.html


Looks like race-condition somewhere.

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]