[muscle] Growing Win32 HANDLE count with repetive connection attempts

  • From: Raymond Dahlberg <rd@xxxxxxxxxxx>
  • To: muscle@xxxxxxxxxxxxx
  • Date: Wed, 06 Oct 2004 09:45:23 +0200

We are using MUSCLE in a Windows XP environment. Our setup have a 
"Teacher PC" which holds the server. This computer will connect to one 
or more client "Student PC's" when the teacher want to start an 
exercise. The computers often resides in different rooms, and are not 
reachable for the teacher from where he sits. So for each exercise start 
we want all the clients to connect automatically. Technically starting 
the exercise means to start the server and connect the clients.

Our current solution is that the clients will try to connect when they 
start up, eventually give up after a timeout (for example 2 seconds), 
and then try again. Like this they will connect automatically when the 
server starts, and when the server stop they will go back to the "try to 
connect" state.

Problem is that after about 30 minutes with no connection (the teacher 
is having lunch and have stopped the exercise for example) the client 
hangs. Inspecting the task manager shows that the number of handles the 
client application holds grows for each connection attempt (about 2 
handles extra per attempt), and it seems that the application freezes 
when it reaches about 10 000 handles.

Pseudo code for what the client do when it tries to connect is as follows:

// This loop goes in the main client application, and will run from the 
application start to we have an
// connection. When the server shuts down, the client will again enter 
this loop and try to connect.
while ( bConnected ) {
   bConnected = client->start( timeout = 2000 ); // Blocking
}

bool Client::start( timeout ) {

    if ( ! _messageTranceiverThread ) {
       _dataSignalHandle = CreateEvent( 0, 0, 0, 0);
       _messageTranceiverThread = new Win32MessageTranceiverThread( 
_dataSignalHandle, true );
    }

    StartInternalThread( );

    do {
       check for connection
       check for timeout     
    } while ( notConnected && time < timeout )

    // We timed out. Stop the thread.
    if ( timeout ) {
       stop( );
       return false;
    }
    // We have an connection
    else {
       return true;
    }
}

Client::stop( ) {

    SetEvent( _shutdownSignalHandle );

    WaitForInternalThreadToExit( );
}

I have tried to check all the HANDLES we explicitly create. For the 
client there is only two HANDLES, the _shutdownSignalHandle (created in 
constructor and deleted in destructor of the Client), and the 
_dataSignalHandle (created each time we create the 
Win32MessageTranceiverThread, and passed to this thread with true as the 
second argument, which I believe mean that the thread will close the 
HANDLE).

Have anyone experienced similar problems? Or is there some obvious 
mistake we do that causes this to happen? Or is there some other way to 
achieve the same automatic connect without starting and stopping the 
thread each time?

Regards, Raymond.

-- 
Raymond Dahlberg
Software Engineer Poseidon Simulation AS



Other related posts: