If many threads are reading from the socket at the same time, then you should put in a CS to lock the socket. Only one thread for reading and one for writing should access the socket should be allowed.
A few years ago, that approach was buggy under older versions of Winsock and select() was the ultimate culprit. I found it was better to ''talk'' directly to Winsock and not the unix emulation layer:
static void service_3_run (DWORD dwArgc, LPTSTR *lpszArgv){ HANDLE l_hEvents[ 2 ]; SOCKET l_sockServer; int l_iRes; svcTime l_sNow = {0, 0}; //---- //---- REPORT: We are in the process of starting... //---- srvReportStatus( SERVICE_3_NAME, &g_ssStatus, g_sshStatusHandle, SERVICE_START_PENDING, NO_ERROR, 0 ); //---- Create the event objects. The control handler //---- function signals this first event when it receives //---- the "stop" control code. The second event //---- is used for overlapped IO calls. l_hEvents[0] = g_hServerStopEvent; l_hEvents[1] = ::WSACreateEvent(); //---- Create the socket that will be used for //---- accepting communications. Put it in a defered //---- accept mode so that we can wait on both the //---- stop and the accept events (and thus force a //---- complete sleep if none occurs). l_iRes = sockUdpServer( SERVICE_3_NAME, DEFAULT_PORT, &l_sockServer ); ::WSAEventSelect( l_sockServer, l_hEvents[1], FD_READ ); //---- Initialize the host list management svrHost_Init(); //---- //---- REPORT: We have started ! //---- srvReportStatus( SERVICE_3_NAME, &g_ssStatus, g_sshStatusHandle, SERVICE_RUNNING, NO_ERROR, 0 ); //---- //---- LOOP: Scan incoming/outgoing data. //---- svcTimeSince( &l_sNow ); while( 1 ) { DWORD l_dwWait; DWORD l_dwErr; double l_dTime; //---- Wait until an event occurs. If it is //---- Event # 0, then this is a STOP command, //---- otherwise this is a new connection. l_dwWait = ::WSAWaitForMultipleEvents( 2, l_hEvents, FALSE, DEFAULT_TIMEOUT, FALSE ); if ( l_dwWait == WSA_WAIT_FAILED ) { l_dwErr = ::WSAGetLastError(); msgMessage( SERVICE_3_NAME, "WSAWaitForMultipleEvents: WSA_WAIT_FAILED error %08X", l_dwErr ); break; } //---- Update the host list. Use the time of the last //---- network exchange to update and flush the host //---- zombies. l_dTime = svcTimeSince( &l_sNow ); svrHost_TimeUpdate( l_dTime ); //---- //---- TIMEOUT -- Periodic check? //---- if ( l_dwWait == WSA_WAIT_TIMEOUT ) continue; //---- //---- STOP ALL -- Exit if this is the STOP signal... //---- if ( l_dwWait == WSA_WAIT_EVENT_0 ) break; //---- //---- SERVER -- This is the server socket being touched. //---- if ( l_dwWait == WSA_WAIT_EVENT_0 + 1 ) { //---- Service the request service_3_process( l_sockServer, dwArgc, lpszArgv ); //---- Reset event. ::WSAEventSelect( l_sockServer, l_hEvents[1], 0 ); ::WSAResetEvent( l_hEvents[1] ); ::WSAEventSelect( l_sockServer, l_hEvents[1], FD_READ ); } } //---- //---- REPORT: We have stopped //---- ::closesocket( l_sockServer ); ::WSACloseEvent( l_hEvents[0] ); srvReportStatus( SERVICE_3_NAME, &g_ssStatus, g_sshStatusHandle, SERVICE_STOPPED, NO_ERROR, 0 );}
I wouldn''t be surprised there are still bugs lurking in there.
-cb