void *FileTransferManager_tep(void *arg) { CFileTransferManager *ftman = (CFileTransferManager *)arg; fd_set f_recv, f_send; struct timeval *tv; struct timeval tv_updates = { 2, 0 }; int l, nSocketsAvailable, nCurrentSocket; char buf[2]; if (ftman->m_nDirection == D_SENDER) { if (!ftman->ConnectToFileServer(ftman->m_nPort)) { ftman->PushFileTransferEvent(FT_ERRORxCONNECT); return NULL; } } else if (ftman->m_nDirection != D_RECEIVER) return NULL; while (true) { f_recv = ftman->sockman.SocketSet(); l = ftman->sockman.LargestSocket() + 1; // Add the new socket pipe descriptor FD_SET(ftman->pipe_thread[PIPE_READ], &f_recv); if (ftman->pipe_thread[PIPE_READ] >= l) l = ftman->pipe_thread[PIPE_READ] + 1; // Set up the send descriptor FD_ZERO(&f_send); if (ftman->m_nState == FT_STATE_SENDINGxFILE) { FD_SET(ftman->ftSock.Descriptor(), &f_send); // No need to check "l" as ftSock is already in the read list } // Prepare max timeout if necessary if (ftman->m_nUpdatesEnabled && (ftman->m_nState == FT_STATE_SENDINGxFILE || ftman->m_nState == FT_STATE_RECEIVINGxFILE) ) { tv_updates.tv_sec = ftman->m_nUpdatesEnabled; tv_updates.tv_usec = 0; tv = &tv_updates; } else { tv = NULL; } nSocketsAvailable = select(l, &f_recv, &f_send, NULL, tv); // Check if we timed out if (tv != NULL && nSocketsAvailable == 0) { ftman->PushFileTransferEvent(FT_UPDATE); gettimeofday(&ftman->tv_lastupdate, NULL); } nCurrentSocket = 0; while (nSocketsAvailable > 0 && nCurrentSocket < l) { if (FD_ISSET(nCurrentSocket, &f_recv)) { // New socket event ---------------------------------------------------- if (nCurrentSocket == ftman->pipe_thread[PIPE_READ]) { read(ftman->pipe_thread[PIPE_READ], buf, 1); if (buf[0] == 'R') { DEBUG_THREADS("[FileTransferManager_tep] Reloading socket info.\n"); } else if (buf[0] == 'X') { DEBUG_THREADS("[FileTransferManager_tep] Exiting.\n"); pthread_exit(NULL); } } // Connection on the server port --------------------------------------- else if (nCurrentSocket == ftman->ftServer.Descriptor()) { if (ftman->ftSock.Descriptor() != -1) { gLog.Warn(tr("%sFile Transfer: Receiving repeat incoming connection.\n"), L_WARNxSTR); } else { ftman->ftServer.RecvConnection(ftman->ftSock); ftman->sockman.AddSocket(&ftman->ftSock); ftman->sockman.DropSocket(&ftman->ftSock); ftman->m_nState = FT_STATE_HANDSHAKE; gLog.Info(tr("%sFile Transfer: Received connection.\n"), L_TCPxSTR); } } // Message from connected socket---------------------------------------- else if (nCurrentSocket == ftman->ftSock.Descriptor()) { ftman->ftSock.Lock(); bool ok = ftman->ProcessPacket(); ftman->ftSock.Unlock(); if (!ok) { ftman->CloseConnection(); ftman->PushFileTransferEvent(ftman->m_nResult); } } else { gLog.Warn(tr("%sFile Transfer: No such socket.\n"), L_WARNxSTR); } nSocketsAvailable--; } else if (FD_ISSET(nCurrentSocket, &f_send)) { if (nCurrentSocket == ftman->ftSock.Descriptor()) { ftman->ftSock.Lock(); bool ok = ftman->SendFilePacket(); ftman->ftSock.Unlock(); if (!ok) { ftman->CloseConnection(); ftman->PushFileTransferEvent(ftman->m_nResult); } } nSocketsAvailable--; } nCurrentSocket++; } } return NULL; }
void *FileTransferManager_tep(void *arg) { CFileTransferManager *ftman = (CFileTransferManager *)arg; fd_set f_recv, f_send; struct timeval *tv; struct timeval tv_updates = { 2, 0 }; int l, nSocketsAvailable, nCurrentSocket; if (!ftman->isReceiver()) { if (!ftman->ConnectToFileServer(ftman->m_nPort)) { ftman->PushFileTransferEvent(FT_ERRORxCONNECT); return NULL; } } else if (!ftman->isReceiver()) return NULL; while (true) { f_recv = ftman->sockman.socketSet(); l = ftman->sockman.LargestSocket() + 1; // Add the new socket pipe descriptor FD_SET(ftman->myThreadPipe.getReadFd(), &f_recv); if (ftman->myThreadPipe.getReadFd() >= l) l = ftman->myThreadPipe.getReadFd() + 1; // Set up the send descriptor FD_ZERO(&f_send); if (ftman->m_nState == FT_STATE_SENDINGxFILE) { FD_SET(ftman->ftSock.Descriptor(), &f_send); // No need to check "l" as ftSock is already in the read list } // Prepare max timeout if necessary if (ftman->m_nUpdatesEnabled && (ftman->m_nState == FT_STATE_SENDINGxFILE || ftman->m_nState == FT_STATE_RECEIVINGxFILE) ) { tv_updates.tv_sec = ftman->m_nUpdatesEnabled; tv_updates.tv_usec = 0; tv = &tv_updates; } else { tv = NULL; } nSocketsAvailable = select(l, &f_recv, &f_send, NULL, tv); if (nSocketsAvailable == -1) { // Something is very wrong, most likely we've lost control of a file // descriptor and select will continue to fail causing this thread to // spin so better to just give up and exit. gLog.warning(tr("File Transfer: select failed, aborting thread: %s"), strerror(errno)); pthread_exit(NULL); } // Check if we timed out if (tv != NULL && nSocketsAvailable == 0) { ftman->PushFileTransferEvent(FT_UPDATE); gettimeofday(&ftman->tv_lastupdate, NULL); } nCurrentSocket = 0; while (nSocketsAvailable > 0 && nCurrentSocket < l) { if (FD_ISSET(nCurrentSocket, &f_recv)) { // New socket event ---------------------------------------------------- if (nCurrentSocket == ftman->myThreadPipe.getReadFd()) { char buf = ftman->myThreadPipe.getChar(); if (buf == 'R') { DEBUG_THREADS("[FileTransferManager_tep] Reloading socket info.\n"); } else if (buf == 'X') { DEBUG_THREADS("[FileTransferManager_tep] Exiting.\n"); pthread_exit(NULL); } } // Connection on the server port --------------------------------------- else if (nCurrentSocket == ftman->ftServer.Descriptor()) { if (ftman->ftSock.Descriptor() != -1) { gLog.warning(tr("File Transfer: Receiving repeat incoming connection.")); // Dump the extra connection to clear the listen socket queue Licq::TCPSocket ts; if (ftman->ftServer.RecvConnection(ts)) ts.CloseConnection(); } else { if (ftman->ftServer.RecvConnection(ftman->ftSock)) { ftman->sockman.AddSocket(&ftman->ftSock); ftman->sockman.DropSocket(&ftman->ftSock); ftman->m_nState = FT_STATE_HANDSHAKE; gLog.info(tr("File Transfer: Received connection.")); } else { gLog.error(tr("File Transfer: Unable to receive new connection.")); } } } // Message from connected socket---------------------------------------- else if (nCurrentSocket == ftman->ftSock.Descriptor()) { ftman->ftSock.Lock(); bool ok = ftman->ProcessPacket(); ftman->ftSock.Unlock(); if (!ok) { ftman->CloseConnection(); ftman->PushFileTransferEvent(ftman->m_nResult); } } else { gLog.warning(tr("File Transfer: No such socket.")); } nSocketsAvailable--; } else if (FD_ISSET(nCurrentSocket, &f_send)) { if (nCurrentSocket == ftman->ftSock.Descriptor()) { ftman->ftSock.Lock(); bool ok = ftman->SendFilePacket(); ftman->ftSock.Unlock(); if (!ok) { ftman->CloseConnection(); ftman->PushFileTransferEvent(ftman->m_nResult); } } nSocketsAvailable--; } nCurrentSocket++; } } return NULL; }
void CNetworkManager::Process() { // Get our file transfer manager CFileTransferManager * pFileTransferManager = g_pClient->GetFileTransfer(); // If our file transfer class exists process it if(pFileTransferManager) pFileTransferManager->Process(); // Have we joined a server and not joined a game yet? if(m_bJoinedServer && !m_bJoinedGame) { // Get our local player CLocalPlayer * pLocalPlayer = g_pClient->GetLocalPlayer(); // Is the file transfer list empty? if(pFileTransferManager->IsComplete() && pLocalPlayer->IsConnectFinished()) { // Flag ourselves as joined a game m_bJoinedGame = true; // Respawn the local player pLocalPlayer->Respawn(); } } if(!m_pNetClient) return; // Process the net client m_pNetClient->Process(); // Are we connected to a server? if(m_pNetClient->IsConnected()) { // If our streamer exists, process it CStreamer * pStreamer = g_pClient->GetStreamer(); if(pStreamer) pStreamer->Pulse(); // Is our script timer manager exists, process it CScriptTimerManager * pScriptTimerManager = g_pClient->GetClientScriptManager()->GetScriptTimerManager(); if(pScriptTimerManager) pScriptTimerManager->Pulse(); // If our player manager exists process it CPlayerManager * pPlayerManager = g_pClient->GetPlayerManager(); if(pPlayerManager) pPlayerManager->Pulse(); // If our vehicle manager exists process it CVehicleManager * pVehicleManager = g_pClient->GetVehicleManager(); if(pVehicleManager) pVehicleManager->Pulse(); // If our checkpoint manager exists process it CCheckpointManager * pCheckpointManager = g_pClient->GetCheckpointManager(); if(pCheckpointManager) pCheckpointManager->Pulse(); // If our object manager exists process it CObjectManager * pObjectManager = g_pClient->GetObjectManager(); if(pObjectManager) pObjectManager->Process(); // Process the audio manager CAudioManager * pAudioManager = g_pClient->GetAudioManager(); if(pAudioManager) pAudioManager->Process(); // Process the actor manager CActorManager * pActorManager = g_pClient->GetActorManager(); if(pActorManager) pActorManager->Process(); } }