Skip to content
This repository has been archived by the owner on Nov 18, 2022. It is now read-only.

Commit

Permalink
fixed #356: crash during download caused by a race condition
Browse files Browse the repository at this point in the history
  • Loading branch information
hugbug committed Mar 31, 2017
1 parent 77f8698 commit 2579ce6
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 21 deletions.
53 changes: 32 additions & 21 deletions daemon/queue/QueueCoordinator.cpp
Expand Up @@ -568,12 +568,14 @@ void QueueCoordinator::ArticleCompleted(ArticleDownloader* articleDownloader)
debug("Article downloaded");

FileInfo* fileInfo = articleDownloader->GetFileInfo();
NzbInfo* nzbInfo = fileInfo->GetNzbInfo();
ArticleInfo* articleInfo = articleDownloader->GetArticleInfo();
bool retry = false;
bool fileCompleted = false;
bool completeFileParts = false;

{
NzbInfo* nzbInfo = fileInfo->GetNzbInfo();
ArticleInfo* articleInfo = articleDownloader->GetArticleInfo();
bool retry = false;
bool fileCompleted = false;

GuardedDownloadQueue downloadQueue = DownloadQueue::Guard();

if (articleDownloader->GetStatus() == ArticleDownloader::adFinished)
Expand Down Expand Up @@ -642,35 +644,44 @@ void QueueCoordinator::ArticleCompleted(ArticleDownloader* articleDownloader)
{
fileCompleted = true;
}
}

bool deleteFileObj = false;
completeFileParts = fileCompleted && (!fileInfo->GetDeleted() || nzbInfo->GetParking());

if (fileCompleted && (!fileInfo->GetDeleted() || nzbInfo->GetParking()))
if (!completeFileParts)
{
DeleteDownloader(downloadQueue, articleDownloader, false);
}
}

if (completeFileParts)
{
// all jobs done
articleDownloader->CompleteFileParts();
fileInfo->SetPartialChanged(false);
deleteFileObj = true;
}

{
GuardedDownloadQueue downloadQueue = DownloadQueue::Guard();
DeleteDownloader(downloadQueue, articleDownloader, true);
}
}

bool hasOtherDownloaders = fileInfo->GetActiveDownloads() > 1;
deleteFileObj |= fileInfo->GetDeleted() && !hasOtherDownloaders;
void QueueCoordinator::DeleteDownloader(DownloadQueue* downloadQueue,
ArticleDownloader* articleDownloader, bool fileCompleted)
{
FileInfo* fileInfo = articleDownloader->GetFileInfo();
NzbInfo* nzbInfo = fileInfo->GetNzbInfo();
bool hasOtherDownloaders = fileInfo->GetActiveDownloads() > 1;
bool deleteFileObj = fileCompleted || (fileInfo->GetDeleted() && !hasOtherDownloaders);

// remove downloader from downloader list
m_activeDownloads.erase(std::find(m_activeDownloads.begin(), m_activeDownloads.end(), articleDownloader));
// remove downloader from downloader list
m_activeDownloads.erase(std::find(m_activeDownloads.begin(), m_activeDownloads.end(), articleDownloader));

fileInfo->SetActiveDownloads(fileInfo->GetActiveDownloads() - 1);
nzbInfo->SetActiveDownloads(nzbInfo->GetActiveDownloads() - 1);
fileInfo->SetActiveDownloads(fileInfo->GetActiveDownloads() - 1);
nzbInfo->SetActiveDownloads(nzbInfo->GetActiveDownloads() - 1);

if (deleteFileObj)
{
DeleteFileInfo(downloadQueue, fileInfo, fileCompleted);
downloadQueue->Save();
}
if (deleteFileObj)
{
DeleteFileInfo(downloadQueue, fileInfo, fileCompleted);
downloadQueue->Save();
}
}

Expand Down
1 change: 1 addition & 0 deletions daemon/queue/QueueCoordinator.h
Expand Up @@ -83,6 +83,7 @@ class QueueCoordinator : public Thread, public Observer, public Debuggable
bool GetNextArticle(DownloadQueue* downloadQueue, FileInfo* &fileInfo, ArticleInfo* &articleInfo);
void StartArticleDownload(FileInfo* fileInfo, ArticleInfo* articleInfo, NntpConnection* connection);
void ArticleCompleted(ArticleDownloader* articleDownloader);
void DeleteDownloader(DownloadQueue* downloadQueue, ArticleDownloader* articleDownloader, bool fileCompleted);
void DeleteFileInfo(DownloadQueue* downloadQueue, FileInfo* fileInfo, bool completed);
void CheckHealth(DownloadQueue* downloadQueue, FileInfo* fileInfo);
void ResetHangingDownloads();
Expand Down

0 comments on commit 2579ce6

Please sign in to comment.