I have a server class that has a method called handle_client as follows:
void server::handle_client()
{
    do {
      // Accept a client socket
      EnterCriticalSection(&listenSocketCriticalSection);
      SOCKET clientSocket = accept(listenSocket, NULL, NULL);
      LeaveCriticalSection(&listenSocketCriticalSection);
      // ... rest of the client handling code that reads
      // from the client socket and sends appropriate response
      // ...
    } while(true);
}
I have a run method as follows:
void server::run()
{
    // create the threads
    for (int i = 0; i < THREAD_POOL_SIZE; i++) {
        DWORD dwThreadId;
        thread_pool_handle[i] = CreateThread(NULL, 0, thread_function, this, 0, &dwThreadId);
    }
    WaitForMultipleObjects(THREAD_POOL_SIZE, thread_pool_handle, true, INFINITE);
}
I have a thread_function as follows:
DWORD WINAPI thread_function(LPVOID lpParam)
{
    server* pServer = (server*)lpParam;
    pServer->handle_client();
}
I am creating a pool of threads that are all waiting for a client socket connection to be accepted. Since I have wrapped the accept within a critical section, only one thread will succeed at a time. Once a client socket is accepted by the server thread, that thread continues to go on to handle the request. The idea is that the thread will loop back indefinitely to the accept call after completing a request.
Questions:
- Is the Critical Section necessary? (I think so, because otherwise the accept call from the multiple threads on the same listenSocket would clobber things. Is this correct?)
 - If 
handle_clientloops indefinitely, what is the best way to cleanly terminate all the threads and exit the server? Should I use a special message from the client to trigger the thread terminations? Any other suggestions? - How should I handle the server process termination gracefully (as it pertains to the thread pool)?