HRESULT CServer::OnDataRecieved() { if (!m_pSocketServer) { return Error(L"Server hasn't been initialised - programming error!"); } if (!m_pIDataInit || !m_pIData) { return Error(L"Internal error: failed to create Data object"); } CCOMSocketServer::Socket *pSocket = m_pSocketServer->GetSocket(); CIOBuffer *pBuffer = m_pSocketServer->GetBuffer(); if (!pSocket || !pBuffer) { return Error(L"Internal error: pSocket or pBuffer is 0"); } ISocket *pISocket = reinterpret_cast<ISocket*>(pSocket->GetUserPtr()); HRESULT hr = m_pIDataInit->Init(pBuffer->GetBuffer(), pBuffer->GetUsed()); if (SUCCEEDED(hr)) { Fire_OnDataReceived(pISocket, m_pIData); // this can stall if the handler doesnt return - // the ATL implementation is difficult to multi thread... } return hr; }
void CSocketServer::Write( Socket *pSocket, const char *pData, size_t dataLength, bool thenShutdown) { if ( !pSocket || !pData || dataLength <= 0 ) { return; } /* * Post a write request to the iocp so that the actual socket write gets performed by * one of our IO threads... */ CIOBuffer *pBuffer = Allocate(); /* * Call to unqualified virtual function */ #ifdef NETWORK_DEBUG //{ PreWrite( pSocket, pBuffer, pData, dataLength + PACK_HEADER_LEN + sizeof(BYTE) ); //} #else //{ PreWrite( pSocket, pBuffer, pData, dataLength ); //} #endif // NETWORK_DEBUG pBuffer->AddData( pData, dataLength ); #ifdef NETWORK_DEBUG //{ const BYTE *pPackData = pBuffer->GetBuffer(); PACK_HEADER ph = {0}; memcpy( (BYTE *)&ph, pPackData, PACK_HEADER_LEN ); pBuffer->AddData( (BYTE *)&ph, PACK_HEADER_LEN ); pBuffer->AddData( 0xAA ); //} #endif // NETWORK_DEBUG pBuffer->SetUserData( IO_Write_Request ); pSocket->AddRef(); m_iocp.PostStatus( (ULONG_PTR)pSocket, thenShutdown, pBuffer ); }
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; }