/* * This function adds a file indicated by filehash to suspended_uploads_list */ uint16 CUploadQueue::SuspendUpload( const CMD4Hash& filehash ) { AddLogLineM( false, CFormat( _("Suspending upload of file: %s" ) ) % filehash.Encode() ); uint16 removed = 0; //Append the filehash to the list. suspended_uploads_list.push_back(filehash); wxString base16hash = filehash.Encode(); CClientPtrList::iterator it = m_uploadinglist.begin(); while (it != m_uploadinglist.end()) { CUpDownClient *potential = *it++; //check if the client is uploading the file we need to suspend if(potential->GetUploadFileID() == filehash) { //remove the unlucky client from the upload queue and add to the waiting queue RemoveFromUploadQueue(potential); m_waitinglist.push_back(potential); theStats::AddWaitingClient(); potential->SetUploadState(US_ONUPLOADQUEUE); potential->SendRankingInfo(); Notify_QlistRefreshClient(potential); Notify_ShowQueueCount(m_waitinglist.size()); removed++; } } return removed; }
/** * Maintenance method for the uploading slots. It adds and removes clients to the * uploading list. It also makes sure that all the uploading slots' Sockets always have * enough packets in their queues, etc. * * This method is called approximately once every 100 milliseconds. */ void CUploadQueue::Process() { DWORD curTick = ::GetTickCount(); UpdateActiveClientsInfo(curTick); if (ForceNewClient()){ // There's not enough open uploads. Open another one. AddUpNextClient(_T("Not enough open upload slots for current ul speed")); } // The loop that feeds the upload slots with data. POSITION pos = uploadinglist.GetHeadPosition(); while(pos != NULL){ // Get the client. Note! Also updates pos as a side effect. CUpDownClient* cur_client = uploadinglist.GetNext(pos); if (thePrefs.m_iDbgHeap >= 2) ASSERT_VALID(cur_client); //It seems chatting or friend slots can get stuck at times in upload.. This needs looked into.. if (!cur_client->socket) { RemoveFromUploadQueue(cur_client, _T("Uploading to client without socket? (CUploadQueue::Process)")); if(cur_client->Disconnected(_T("CUploadQueue::Process"))){ delete cur_client; } } else { cur_client->SendBlockData(); } } // Save used bandwidth for speed calculations uint64 sentBytes = theApp.uploadBandwidthThrottler->GetNumberOfSentBytesSinceLastCallAndReset(); avarage_dr_list.AddTail(sentBytes); m_avarage_dr_sum += sentBytes; (void)theApp.uploadBandwidthThrottler->GetNumberOfSentBytesOverheadSinceLastCallAndReset(); avarage_friend_dr_list.AddTail(theStats.sessionSentBytesToFriend); // Save time beetween each speed snapshot avarage_tick_list.AddTail(curTick); // don't save more than 30 secs of data while(avarage_tick_list.GetCount() > 3 && !avarage_friend_dr_list.IsEmpty() && ::GetTickCount()-avarage_tick_list.GetHead() > 30*1000) { m_avarage_dr_sum -= avarage_dr_list.RemoveHead(); avarage_friend_dr_list.RemoveHead(); avarage_tick_list.RemoveHead(); } };
void CUploadQueue::Process() { // Check if someone's waiting, if there is a slot for him, // or if we should try to free a slot for him uint32 tick = GetTickCount(); // Nobody waiting or upload started recently // (Actually instead of "empty" it should check for "no HighID clients queued", // but the cost for that outweights the benefit. As it is, a slot will be freed // even if it can't be taken because all of the queue is LowID. But just one, // and the kicked client will instantly get it back if he has HighID.) if (m_waitinglist.empty() || tick - m_nLastStartUpload < 1000) { m_allowKicking = false; // Already a slot free, try to fill it } else if (m_uploadinglist.size() < GetMaxSlots()) { m_allowKicking = false; m_nLastStartUpload = tick; AddUpNextClient(); // All slots taken, try to free one } else { m_allowKicking = true; } // The loop that feeds the upload slots with data. CClientPtrList::iterator it = m_uploadinglist.begin(); while (it != m_uploadinglist.end()) { // Get the client. Note! Also updates pos as a side effect. CUpDownClient* cur_client = *it++; // It seems chatting or friend slots can get stuck at times in upload.. This needs looked into.. if (!cur_client->GetSocket()) { RemoveFromUploadQueue(cur_client); if(cur_client->Disconnected(_T("CUploadQueue::Process"))){ cur_client->Safe_Delete(); } } else { cur_client->SendBlockData(); } } // Save used bandwidth for speed calculations uint64 sentBytes = theApp->uploadBandwidthThrottler->GetNumberOfSentBytesSinceLastCallAndReset(); (void)theApp->uploadBandwidthThrottler->GetNumberOfSentBytesOverheadSinceLastCallAndReset(); // Update statistics if (sentBytes) { theStats::AddSentBytes(sentBytes); } }