Boost logo

Boost Users :

Subject: Re: [Boost-users] Switching from CreateThread to boost::thread
From: OvermindDL1 (overminddl1_at_[hidden])
Date: 2010-02-05 16:15:30


On Fri, Feb 5, 2010 at 10:38 AM, Kurt D. Knudsen <kknudsen_at_[hidden]> wrote:
> Hi all,
>
> Currently, I'm working on a Windows C++ program that was developed by a
> third party and I'm just working out the kinks and adding new features. I'm
> not 100% familar with threads, but I think I have the general idea down. The
> project is a client/server backup solution. The problem I am running into is
> this after the code pasted below:
>
> void CTransferServer::startCommandThread() {
>  int iCommandPort =
> _wtoi(configHandler->getTextValue(L"TransferCommandPort"));
>  SOCKET socCommand = CSocHandler::getServerSocket(iCommandPort);
>  if (socCommand == INVALID_SOCKET) {
>   //cout << "\nCould not create transfer command server socket." <<
> WSAGetLastError();
>   return;
>  }
>
>  if (listen(socCommand, SOMAXCONN)) {
>   //cout << "\nCould not listen on transfer command port." <<
> WSAGetLastError();
>   return;
>  }
>  while (blStarted) {
>   SOCKET sa = accept(socCommand, 0, 0);                  // block for
> connection request
>   if (sa ==INVALID_SOCKET) {
>    break;
>   }
>
>   void **params = (void **) malloc(sizeof(void*)*2);
>   SOCKET *s = new SOCKET;
>   *s = sa;
>   params[0] = (void*)this;
>   params[1] = (void*)s;
>   DWORD dwGenericThread;
>   //unsigned int iGenericThread;
>   HANDLE hWorkerThread = CreateThread(NULL, 0, transferCommandWorkerThread,
> params, 0, &dwGenericThread);
>   //HANDLE hWorkerThread = (HANDLE)_beginthreadex(NULL, 0,
> transferCommandWorkerThread, params, 0, &iGenericThread);
>   wcout << "Transfer Server worker command handle: " << hWorkerThread <<
> endl;
>   //WaitForSingleObject(hWorkerThread, INFINITE);
>   //CloseHandle(hWorkerThread);
>  }
> }
>
>
> You can see the while-loop that creates a socket that accepts a connection,
> it then passes this socket off as a parameter used in the thread creation.
> Here's the code for the transferCommandWorkerThread:
> DWORD WINAPI transferCommandWorkerThread(LPVOID param) {
>  void **params = (void **)param;
>  CTransferServer *transferServer = (CTransferServer*)params[0];
>  SOCKET *commandSocket = (SOCKET*)params[1];
>  transferServer->handleCommandConnection(*commandSocket);
>  delete commandSocket;
>  free((void*)params);
>  return 0;
> }
>
> So this workerThread passes the socket off to another function that handles
> the command connection and then deletes/frees the data used. All that aside,
> here's the issue. This while-loop generates hundreds of thousands of handles
> in a matter of days. This causes all kinds of problems on the server
> (there's a similar issue with clients using identical functions) and either
> the server needs to be rebooted or the program shut down. I tried to use
> WaitForSingleObject() and then CloseHandle() but it seems to close the
> handle prematurely. This causes the client/server to not communicate and
> interrupt any data transfer. I am wondering if using boost::thread will make
> handling the destruction of the threads easier. I've been researching it but
> I can't find any solid information on whether or not CloseHandle(), or
> something similar, needs to be run. I'm just trying to see if using Boost is
> the right direction to go.

We got your email with the source code, always prefer it in the email
or as an attachment anyway, not as an external temporary link.
You actually should be passing the socket to the handler so it can
free it whenever it is done, plus you should sleep for a millisecond
or so to transfer command to that thread, but if you want the best
possible speed, instead of making your own solution like that you
really should use Boost.ASIO instead, it handles all of that *very*
efficiently.


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net