Click here to Skip to main content
15,922,015 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
See more:
I am writing a server application which has a socket which listens for a connection request from a client. There will only ever be one client. So I have a while(1) loop which checks if there is a socket connection to a client and contains the accept() method. When accept() returns, a new thread is created to handle the client connection. If the client disconnects, the while(1) loop will detect this using getsockname() and then allow accept() to make another connection and a new thread to handle the connection.

I want to ensure that if a socket connection is closed that I close its thread handle as well in order to prevent a memory leak. But I need to do this in the while(1) loop. The first time this loop is entered after startup, the handle will not be valid, so if I do CloseHandle(hThread), I get an error. If I check if(hThread != NULL) before I call CloseHandle(hThread) it still complains about the 'if' statement because the handle is invalid. How can I chnage my code to ensure I deallocate the memory for the thread handle before a new one is created?

Please could somebody tell me where I am going wrong.

DWORD WINAPI StartListeningThread(void *param)//(LPVOID iValue)
{
	CCCDSocket listenSock;
	SOCKET ls;
        HANDLE hRecvThread; 

	//create socket up to and including listen()
	bool listenSockReturn = listenSock.CreateListeningSocket(ls);
	
	//continually check if the listening socket has accepted a connection
        //request from a client, and a socket connection has been made. If the
        //connected socket loses its connection, accept a new connection request
	while(1) 
	{
                if(hRecvThread != NULL)//this causes an error at run-time as the 
                                       //hRecvThread is not valid!!! But that is
                                       //what I want to test for.
                {
                    CloseHandle(hRecvThread)
                }

         	//check if the connected socket has been closed, as then a new 
                //connection request needs to be accepted
		struct sockaddr_storage addr;
		int addrLen = sizeof(addr);

                //this will fail if the socket has been closed
		if(getsockname(sr,(LPSOCKADDR)&addr, &addrLen) ==SOCKET_ERROR)
		{
			//accept the new connection request from the client 
			sr = accept(ls, 0, 0);

			DWORD dwClientHandlerThreadID;
			hRecvThread = CreateThread(NULL, NULL, 
                                                    CreateClientHandlerThread, 
                                                    NULL, NULL, 
                                                    &dwClientHandlerThreadID);
		}
	}
	return 0;		
}
Posted
Updated 3-Apr-12 22:35pm
v2

1 solution

The first part is easy but it won't solve your problems.

CSS
HANDLE hRecvThread = NULL;



The second part is more difficult. This is not the way to terminate a thread.

1. You must allow the thread main to exit itself. This is a tricky process if the thread is blocked (waiting).
2. You can then wait on the thread handle to be signaled indicating thread has exited.
3. You may then call CloseHandle() on the thread handle.

This gives you the idea.

C++
dwResult = ::WaitForSingleObject(m_hThread, killTimeOut);

switch(dwResult)
{
    // If get to here then thread exits normally.
    case WAIT_OBJECT_0:
        ::CloseHandle(m_hThread);
         m_hThread = NULL;
    break;

    case WAIT_TIMEOUT:
    default:
        bRetVal = false;
    break;
}


The overheads and time delays involved here usually means some kind of thread pooling is used in servers. This avoids having to destroy and create threads on the fly.

http://msdn.microsoft.com/en-us/library/windows/desktop/ms686724(v=vs.85).aspx[^]
 
Share this answer
 
v3
Comments
Jackie Lloyd 4-Apr-12 9:11am    
Thankyou very much. I did a bit of playing around with this idea and have learnt something very useful. Also I will look up thread pooling as that sounds a useful thing to know about too.
[no name] 4-Apr-12 9:20am    
Thanks - its quite a big subject.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900