unsigned Listener::Process() { //Profile profile("Listener::Process"); //////////////////////////////////////// // handle inactive state (with UdpManager) if (!IsActive() && mTcpManager) { // check all connections to see if they are idle std::set<Connection *>::iterator iterator; for (iterator = mConnections.begin(); iterator != mConnections.end(); iterator++) { Connection * connection = *iterator; if (connection->IsConnected()) connection->Disconnect(); } // close the UdpManager if all the connections are closed if (!mConnectionCount) { mTcpManager->Release(); mTcpManager = 0; OnShutdown(); } } //////////////////////////////////////// // handle active state (without UdpManager) else if (IsActive() && !mTcpManager) { mParams = GetConnectionParams(); mActiveMax = GetActiveRequestMax(); mTcpManager = new TcpManager(mParams); mTcpManager->SetHandler(this); if (mTcpManager->BindAsServer()){ OnStartup(); }else{ OnFailedStartup(); return 0; } } //////////////////////////////////////// // process the TcpManager if (mTcpManager) { //Profile subProfile("TcpManager::GiveTime()"); mTcpManager->GiveTime(); } // check all closed connections to see if they are idle std::list<Connection *>::iterator closedIterator = mClosedConnections.begin(); while (closedIterator != mClosedConnections.end()) { //Profile profile("Listener::Process (cleanup connection)"); std::list<Connection *>::iterator current = closedIterator++; Connection * connection = *current; if (!connection->GetActiveRequests() && !connection->GetQueuedRequests()) { mClosedConnections.erase(current); mConnections.erase(connection); mConnectionCount--; OnConnectionDestroyed(connection); delete connection; } } //////////////////////////////////////// // process request queue while (!mQueuedRequests.empty() && (!mActiveMax || mActiveCount < mActiveMax)) { //Profile profile("Listener::Process (activate queued request)"); QueueNode & node = mQueuedRequests.front(); if (!IsActive()) { // If not active, discard queued request if (node.connection) { // normal request, internal requests have no connection node.connection->NotifyDiscardRequest(node.request); } DestroyRequest(node.request); } else { // Move request to active list if (node.connection) { // normal request, internal requests have no connection node.connection->NotifyBeginRequest(node.request); } mActiveRequests.push_back(node); mActiveCount++; } mQueuedRequests.pop_front(); } //////////////////////////////////////// // Process active requests unsigned requestsProcessed = 0; std::list<QueueNode>::iterator iterator = mActiveRequests.begin(); while (iterator != mActiveRequests.end()) { //Profile profile("Listener::Process (process request)"); std::list<QueueNode>::iterator current = iterator++; RequestBase * request = current->request; Connection * connection = current->connection; if (request->Process()) { if (connection) { // normal request, internal requests have no connection connection->NotifyEndRequest(request); } DestroyRequest(request); mActiveRequests.erase(current); mActiveCount--; } else if (mSleepingRequests.find(request) != mSleepingRequests.end()) { mActiveRequests.erase(current); } requestsProcessed++; } return requestsProcessed; }
int32 TCPManager::_Manager_Thread() { // set_alarm(25000,B_PERIODIC_ALARM); Connection *connection; int32 connect_count; int32 current_time; // int32 last_used; int32 time_out=DEFAULT_TIMEOUT; while(!_quitter_) { // if (acquire_sem(process_sem_1)==B_OK) { // printf("processing\n"); connect_count=Connection::CountConnections(); if (connect_count>0) { current_time=real_time_clock(); for (int32 i=0; i<connect_count; i++) { if (lock.LockWithTimeout(25000)==B_OK) { // printf("TCP Manager: lock acquired\n"); connection=Connection::ConnectionAt(i); if (!Connection::HasConnection(connection)) { lock.Unlock(); snooze(10000); continue; } if (connection->IsConnected()) { if (connection->IsInUse()) { if (!connection->NotifiedConnect()) { if (!connection->already_connected) connection->ConnectionEstablished(); connection->NotifyConnect(); } else { if (connection->IsDataWaiting()) { connection->RetrieveData(); if (connection->owner!=NULL) connection->owner->DataIsWaiting(connection); } } } else { if (connection->IsDataWaiting()) { // printf("TCP Manager: data is waiting on unused connection; receiving and flushing data\n"); int32 lastused=connection->LastUsed(); connection->RetrieveData(); connection->lastusedtime=lastused; } } if ((connection->LastUsed()!=0) && ((current_time-connection->LastUsed())>=time_out)) { // if (connection->owner!=NULL) // connection->owner->DestroyingConnectionObject(connection); connection->TimeOut(); Disconnect(connection); } } else { if (!connection->NotifiedDisconnect()) { connection->NotifyDisconnect(); // Disconnect(connection); } else { if ((connection->LastUsed()!=0) && ((current_time-connection->LastUsed())>=time_out)) { // if (connection->owner!=NULL) // connection->owner->DestroyingConnectionObject(connection); connection->TimeOut(); Disconnect(connection); } } } lock.Unlock(); } snooze(10000); } } snooze(25000); // release_sem(process_sem_2); // } } // set_alarm(B_INFINITE_TIMEOUT,B_PERIODIC_ALARM); atomic_add(&Connection::SystemReady,-1); return 0; }