int CSocketServer::WorkerThread::Run() { try { while ( true ) { /* * Continually loop to service io completion packets */ bool closeSocket = false; DWORD dwIoSize = 0; Socket *pSocket = 0; CIOBuffer *pBuffer = 0; try { m_iocp.GetStatus( (PDWORD_PTR)&pSocket, &dwIoSize, (OVERLAPPED **)&pBuffer ); } catch (const CWin32Exception &e) { if ( e.GetError() != ERROR_NETNAME_DELETED && e.GetError() != WSA_OPERATION_ABORTED ) { throw; } Output( _T("IOCP error [client connection dropped] - ") + GetLastErrorMessage( ::WSAGetLastError() ) ); closeSocket = true; } if ( !pSocket ) { /* * A completion key of 0 is posted to the iocp to request us to shut down... */ break; } /* * Call to unqualified virtual function */ OnBeginProcessing(); if ( pBuffer ) { const IO_Operation operation = static_cast<IO_Operation>( pBuffer->GetUserData() ); switch ( operation ) { case IO_Read_Request: Read( pSocket, pBuffer ); break; case IO_Read_Completed : if ( 0 != dwIoSize ) { pBuffer->Use( dwIoSize ); //DEBUG_ONLY( Output(_T("RX: ") + ToString(pBuffer) + _T("\n") + DumpData(reinterpret_cast<const BYTE*>( pBuffer->GetWSABUF()->buf), dwIoSize, 40) ) ); /* * Call to unqualified virtual function */ ReadCompleted( pSocket, pBuffer ); } else { /* * client connection dropped... */ Output( _T("ReadCompleted - 0 bytes - client connection dropped") ); closeSocket = true; } pSocket->Release(); pBuffer->Release(); break; case IO_Write_Request : Write( pSocket, pBuffer ); if ( dwIoSize != 0 ) { /* * final write, now shutdown send side of connection */ pSocket->Shutdown( SD_SEND ); } break; case IO_Write_Completed : pBuffer->Use( dwIoSize ); //DEBUG_ONLY( Output(_T("TX: ") + ToString(pBuffer) + _T("\n") + DumpData(reinterpret_cast<const BYTE*>( pBuffer->GetWSABUF()->buf), dwIoSize, 40) ) ); /* * Call to unqualified virtual function */ WriteCompleted( pSocket, pBuffer ); pSocket->Release(); pBuffer->Release(); break; case IO_Close : AbortiveClose( pSocket ); pSocket->Release(); pBuffer->Release(); break; default : /* * all to unqualified virtual function */ OnError( _T("CSocketServer::WorkerThread::Run() - Unexpected operation") ); break; } } else { /* * Call to unqualified virtual function */ OnError( _T("CSocketServer::WorkerThread::Run() - Unexpected - pBuffer is 0") ); } if ( closeSocket ) { pSocket->Close(); } /* * Call to unqualified virtual function */ OnEndProcessing(); } } catch(const CException &e) { /* * Call to unqualified virtual function */ OnError( _T("CSocketServer::WorkerThread::Run() - Exception: ") + e.GetWhere() + _T(" - ") + e.GetMessage() ); } catch(...) { /* * Call to unqualified virtual function */ OnError( _T("CSocketServer::WorkerThread::Run() - Unexpected exception") ); } return 0; }
int CSocketServer::Run() { try { vector<WorkerThread *> workers; workers.reserve( m_numThreads ); for ( size_t i = 0; i < m_numThreads; ++i ) { /* * Call to unqualified virtual function */ WorkerThread *pThread = CreateWorkerThread( m_iocp ); workers.push_back( pThread ); pThread->Start(); } HANDLE handlesToWaitFor[2]; handlesToWaitFor[0] = m_shutdownEvent.GetEvent(); handlesToWaitFor[1] = m_acceptConnectionsEvent.GetEvent(); while ( !m_shutdownEvent.Wait( 0 ) ) { DWORD waitResult = ::WaitForMultipleObjects( 2, handlesToWaitFor, false, INFINITE ); if ( waitResult == WAIT_OBJECT_0 ) { /* * Time to shutdown */ break; } else if ( waitResult == WAIT_OBJECT_0 + 1 ) { /* * accept connections */ while ( !m_shutdownEvent.Wait( 0 ) && m_acceptConnectionsEvent.Wait( 0 ) ) { CIOBuffer *pAddress = Allocate(); int addressSize = (int)pAddress->GetSize(); SOCKET acceptedSocket = ::WSAAccept( m_listeningSocket, reinterpret_cast<sockaddr *>(const_cast<BYTE *>( pAddress->GetBuffer() ) ), &addressSize, 0, 0); pAddress->Use( addressSize ); if ( acceptedSocket != INVALID_SOCKET ) { Socket *pSocket = AllocateSocket( acceptedSocket ); /* * Call to unqualified virtual function */ OnConnectionEstablished( pSocket, pAddress ); } else if ( m_acceptConnectionsEvent.Wait( 0 ) ) { /* * Call to unqualified virtual function */ OnError( _T("CSocketServer::Run() - WSAAccept:") + GetLastErrorMessage( ::WSAGetLastError() ) ); } pAddress->Release(); } } else { /* * Call to unqualified virtual function */ OnError( _T("CSocketServer::Run() - WaitForMultipleObjects: ") + GetLastErrorMessage( ::GetLastError() ) ); } } for ( i = 0; i < m_numThreads; ++i ) { workers[i]->InitiateShutdown(); } for ( i = 0; i < m_numThreads; ++i ) { workers[i]->WaitForShutdownToComplete(); delete workers[i]; workers[i] = 0; } } catch( const CException &e ) { /* * Call to unqualified virtual function */ OnError( _T("CSocketServer::Run() - Exception: ") + e.GetWhere() + _T(" - ") + e.GetMessage() ); } catch(...) { /* * Call to unqualified virtual function */ OnError( _T("CSocketServer::Run() - Unexpected exception") ); } /* * Call to unqualified virtual function */ OnShutdownComplete(); return 0; }