Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
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;
}