void UrlCoordinator::Run() { debug("Entering UrlCoordinator-loop"); while (!DownloadQueue::IsLoaded()) { usleep(20 * 1000); } int resetCounter = 0; while (!IsStopped()) { bool downloadStarted = false; if (!g_Options->GetPauseDownload() || g_Options->GetUrlForce()) { // start download for next URL GuardedDownloadQueue downloadQueue = DownloadQueue::Guard(); if ((int)m_activeDownloads.size() < g_Options->GetUrlConnections()) { NzbInfo* nzbInfo = GetNextUrl(downloadQueue); bool hasMoreUrls = nzbInfo != nullptr; bool urlDownloadsRunning = !m_activeDownloads.empty(); m_hasMoreJobs = hasMoreUrls || urlDownloadsRunning; if (hasMoreUrls && !IsStopped()) { StartUrlDownload(nzbInfo); downloadStarted = true; } } } int sleepInterval = downloadStarted ? 0 : 100; usleep(sleepInterval * 1000); resetCounter += sleepInterval; if (resetCounter >= 1000) { // this code should not be called too often, once per second is OK ResetHangingDownloads(); resetCounter = 0; } } WaitJobs(); debug("Exiting UrlCoordinator-loop"); }
void UrlCoordinator::WaitJobs() { // waiting for downloads debug("UrlCoordinator: waiting for Downloads to complete"); while (true) { { GuardedDownloadQueue guard = DownloadQueue::Guard(); if (m_activeDownloads.empty()) { break; } } usleep(100 * 1000); ResetHangingDownloads(); } debug("UrlCoordinator: Downloads are completed"); }
void QueueCoordinator::Run() { debug("Entering QueueCoordinator-loop"); Load(); AdjustDownloadsLimit(); bool bWasStandBy = true; bool bArticeDownloadsRunning = false; int iResetCounter = 0; g_pStatMeter->IntervalCheck(); while (!IsStopped()) { bool bDownloadsChecked = false; bool bDownloadStarted = false; NNTPConnection* pConnection = g_pServerPool->GetConnection(0, NULL, NULL); if (pConnection) { // start download for next article FileInfo* pFileInfo; ArticleInfo* pArticleInfo; bool bFreeConnection = false; DownloadQueue* pDownloadQueue = DownloadQueue::Lock(); bool bHasMoreArticles = GetNextArticle(pDownloadQueue, pFileInfo, pArticleInfo); bArticeDownloadsRunning = !m_ActiveDownloads.empty(); bDownloadsChecked = true; m_bHasMoreJobs = bHasMoreArticles || bArticeDownloadsRunning; if (bHasMoreArticles && !IsStopped() && (int)m_ActiveDownloads.size() < m_iDownloadsLimit && (!g_pOptions->GetTempPauseDownload() || pFileInfo->GetExtraPriority())) { StartArticleDownload(pFileInfo, pArticleInfo, pConnection); bArticeDownloadsRunning = true; bDownloadStarted = true; } else { bFreeConnection = true; } DownloadQueue::Unlock(); if (bFreeConnection) { g_pServerPool->FreeConnection(pConnection, false); } } if (!bDownloadsChecked) { DownloadQueue::Lock(); bArticeDownloadsRunning = !m_ActiveDownloads.empty(); DownloadQueue::Unlock(); } bool bStandBy = !bArticeDownloadsRunning; if (bStandBy != bWasStandBy) { g_pStatMeter->EnterLeaveStandBy(bStandBy); bWasStandBy = bStandBy; if (bStandBy) { SavePartialState(); } } // sleep longer in StandBy int iSleepInterval = bDownloadStarted ? 0 : bStandBy ? 100 : 5; usleep(iSleepInterval * 1000); if (!bStandBy) { g_pStatMeter->AddSpeedReading(0); } Util::SetStandByMode(bStandBy); iResetCounter += iSleepInterval; if (iResetCounter >= 1000) { // this code should not be called too often, once per second is OK g_pServerPool->CloseUnusedConnections(); ResetHangingDownloads(); if (!bStandBy) { SavePartialState(); } iResetCounter = 0; g_pStatMeter->IntervalCheck(); AdjustDownloadsLimit(); } } // waiting for downloads debug("QueueCoordinator: waiting for Downloads to complete"); bool completed = false; while (!completed) { DownloadQueue::Lock(); completed = m_ActiveDownloads.size() == 0; DownloadQueue::Unlock(); usleep(100 * 1000); ResetHangingDownloads(); } debug("QueueCoordinator: Downloads are completed"); SavePartialState(); debug("Exiting QueueCoordinator-loop"); }