void ParCoordinator::UpdateParCheckProgress() { DownloadQueue::Lock(); PostInfo* pPostInfo = m_ParChecker.GetPostInfo(); if (m_ParChecker.GetFileProgress() == 0) { pPostInfo->SetProgressLabel(m_ParChecker.GetProgressLabel()); } pPostInfo->SetFileProgress(m_ParChecker.GetFileProgress()); pPostInfo->SetStageProgress(m_ParChecker.GetStageProgress()); PostInfo::EStage StageKind[] = { PostInfo::ptLoadingPars, PostInfo::ptVerifyingSources, PostInfo::ptRepairing, PostInfo::ptVerifyingRepaired }; PostInfo::EStage eStage = StageKind[m_ParChecker.GetStage()]; time_t tCurrent = time(NULL); if (pPostInfo->GetStage() != eStage) { pPostInfo->SetStage(eStage); pPostInfo->SetStageTime(tCurrent); if (pPostInfo->GetStage() == PostInfo::ptRepairing) { m_ParChecker.SetRepairTime(tCurrent); } else if (pPostInfo->GetStage() == PostInfo::ptVerifyingRepaired) { int iRepairSec = (int)(tCurrent - m_ParChecker.GetRepairTime()); pPostInfo->GetNZBInfo()->SetRepairSec(pPostInfo->GetNZBInfo()->GetRepairSec() + iRepairSec); } } bool bParCancel = false; if (!m_ParChecker.GetCancelled()) { if ((g_pOptions->GetParTimeLimit() > 0) && m_ParChecker.GetStage() == ParChecker::ptRepairing && ((g_pOptions->GetParTimeLimit() > 5 && tCurrent - pPostInfo->GetStageTime() > 5 * 60) || (g_pOptions->GetParTimeLimit() <= 5 && tCurrent - pPostInfo->GetStageTime() > 1 * 60))) { // first five (or one) minutes elapsed, now can check the estimated time int iEstimatedRepairTime = (int)((tCurrent - pPostInfo->GetStartTime()) * 1000 / (pPostInfo->GetStageProgress() > 0 ? pPostInfo->GetStageProgress() : 1)); if (iEstimatedRepairTime > g_pOptions->GetParTimeLimit() * 60) { debug("Estimated repair time %i seconds", iEstimatedRepairTime); m_ParChecker.PrintMessage(Message::mkWarning, "Cancelling par-repair for %s, estimated repair time (%i minutes) exceeds allowed repair time", m_ParChecker.GetInfoName(), iEstimatedRepairTime / 60); bParCancel = true; } } } if (bParCancel) { m_ParChecker.Cancel(); } DownloadQueue::Unlock(); CheckPauseState(pPostInfo); }
void PrePostProcessor::CleanupJobs(DownloadQueue* downloadQueue) { m_activeJobs.erase(std::remove_if(m_activeJobs.begin(), m_activeJobs.end(), [processor = this, downloadQueue](NzbInfo* postJob) { PostInfo* postInfo = postJob->GetPostInfo(); if (!postInfo->GetWorking() && !(postInfo->GetPostThread() && postInfo->GetPostThread()->IsRunning())) { delete postInfo->GetPostThread(); postInfo->SetPostThread(nullptr); postInfo->SetStageTime(0); postInfo->SetStageProgress(0); postInfo->SetFileProgress(0); postInfo->SetProgressLabel(""); if (postInfo->GetStartTime() > 0) { postJob->SetPostTotalSec(postJob->GetPostTotalSec() + (int)(Util::CurrentTime() - postInfo->GetStartTime())); postInfo->SetStartTime(0); } if (postInfo->GetStage() == PostInfo::ptFinished || postInfo->GetDeleted()) { processor->JobCompleted(downloadQueue, postInfo); } else { postInfo->SetStage(PostInfo::ptQueued); } return true; } return false; }), m_activeJobs.end()); }
void ParCoordinator::ParCheckCompleted() { DownloadQueue* pDownloadQueue = DownloadQueue::Lock(); PostInfo* pPostInfo = m_ParChecker.GetPostInfo(); // Update ParStatus (accumulate result) if ((m_ParChecker.GetStatus() == ParChecker::psRepaired || m_ParChecker.GetStatus() == ParChecker::psRepairNotNeeded) && pPostInfo->GetNZBInfo()->GetParStatus() <= NZBInfo::psSkipped) { pPostInfo->GetNZBInfo()->SetParStatus(NZBInfo::psSuccess); pPostInfo->SetParRepaired(m_ParChecker.GetStatus() == ParChecker::psRepaired); } else if (m_ParChecker.GetStatus() == ParChecker::psRepairPossible && pPostInfo->GetNZBInfo()->GetParStatus() != NZBInfo::psFailure) { pPostInfo->GetNZBInfo()->SetParStatus(NZBInfo::psRepairPossible); } else { pPostInfo->GetNZBInfo()->SetParStatus(NZBInfo::psFailure); } int iWaitTime = pPostInfo->GetNZBInfo()->GetDownloadSec() - m_ParChecker.GetDownloadSec(); pPostInfo->SetStartTime(pPostInfo->GetStartTime() + (time_t)iWaitTime); int iParSec = (int)(time(NULL) - m_ParChecker.GetParTime()) - iWaitTime; pPostInfo->GetNZBInfo()->SetParSec(pPostInfo->GetNZBInfo()->GetParSec() + iParSec); pPostInfo->GetNZBInfo()->SetParFull(m_ParChecker.GetParFull()); pPostInfo->SetWorking(false); pPostInfo->SetStage(PostInfo::ptQueued); pDownloadQueue->Save(); DownloadQueue::Unlock(); }
void PostQueueBinCommand::Execute() { SNZBPostQueueRequest PostQueueRequest; if (!ReceiveRequest(&PostQueueRequest, sizeof(PostQueueRequest))) { return; } SNZBPostQueueResponse PostQueueResponse; memset(&PostQueueResponse, 0, sizeof(PostQueueResponse)); PostQueueResponse.m_MessageBase.m_iSignature = htonl(NZBMESSAGE_SIGNATURE); PostQueueResponse.m_MessageBase.m_iStructSize = htonl(sizeof(PostQueueResponse)); PostQueueResponse.m_iEntrySize = htonl(sizeof(SNZBPostQueueResponseEntry)); char* buf = NULL; int bufsize = 0; // Make a data structure and copy all the elements of the list into it PostQueue* pPostQueue = g_pQueueCoordinator->LockQueue()->GetPostQueue(); int NrEntries = pPostQueue->size(); // calculate required buffer size bufsize = NrEntries * sizeof(SNZBPostQueueResponseEntry); for (PostQueue::iterator it = pPostQueue->begin(); it != pPostQueue->end(); it++) { PostInfo* pPostInfo = *it; bufsize += strlen(pPostInfo->GetNZBInfo()->GetFilename()) + 1; bufsize += strlen(pPostInfo->GetParFilename()) + 1; bufsize += strlen(pPostInfo->GetInfoName()) + 1; bufsize += strlen(pPostInfo->GetNZBInfo()->GetDestDir()) + 1; bufsize += strlen(pPostInfo->GetProgressLabel()) + 1; // align struct to 4-bytes, needed by ARM-processor (and may be others) bufsize += bufsize % 4 > 0 ? 4 - bufsize % 4 : 0; } time_t tCurTime = time(NULL); buf = (char*) malloc(bufsize); char* bufptr = buf; for (PostQueue::iterator it = pPostQueue->begin(); it != pPostQueue->end(); it++) { PostInfo* pPostInfo = *it; SNZBPostQueueResponseEntry* pPostQueueAnswer = (SNZBPostQueueResponseEntry*) bufptr; pPostQueueAnswer->m_iID = htonl(pPostInfo->GetID()); pPostQueueAnswer->m_iStage = htonl(pPostInfo->GetStage()); pPostQueueAnswer->m_iStageProgress = htonl(pPostInfo->GetStageProgress()); pPostQueueAnswer->m_iFileProgress = htonl(pPostInfo->GetFileProgress()); pPostQueueAnswer->m_iTotalTimeSec = htonl((int)(pPostInfo->GetStartTime() ? tCurTime - pPostInfo->GetStartTime() : 0)); pPostQueueAnswer->m_iStageTimeSec = htonl((int)(pPostInfo->GetStageTime() ? tCurTime - pPostInfo->GetStageTime() : 0)); pPostQueueAnswer->m_iNZBFilenameLen = htonl(strlen(pPostInfo->GetNZBInfo()->GetFilename()) + 1); pPostQueueAnswer->m_iParFilename = htonl(strlen(pPostInfo->GetParFilename()) + 1); pPostQueueAnswer->m_iInfoNameLen = htonl(strlen(pPostInfo->GetInfoName()) + 1); pPostQueueAnswer->m_iDestDirLen = htonl(strlen(pPostInfo->GetNZBInfo()->GetDestDir()) + 1); pPostQueueAnswer->m_iProgressLabelLen = htonl(strlen(pPostInfo->GetProgressLabel()) + 1); bufptr += sizeof(SNZBPostQueueResponseEntry); strcpy(bufptr, pPostInfo->GetNZBInfo()->GetFilename()); bufptr += ntohl(pPostQueueAnswer->m_iNZBFilenameLen); strcpy(bufptr, pPostInfo->GetParFilename()); bufptr += ntohl(pPostQueueAnswer->m_iParFilename); strcpy(bufptr, pPostInfo->GetInfoName()); bufptr += ntohl(pPostQueueAnswer->m_iInfoNameLen); strcpy(bufptr, pPostInfo->GetNZBInfo()->GetDestDir()); bufptr += ntohl(pPostQueueAnswer->m_iDestDirLen); strcpy(bufptr, pPostInfo->GetProgressLabel()); bufptr += ntohl(pPostQueueAnswer->m_iProgressLabelLen); // align struct to 4-bytes, needed by ARM-processor (and may be others) if ((size_t)bufptr % 4 > 0) { pPostQueueAnswer->m_iProgressLabelLen = htonl(ntohl(pPostQueueAnswer->m_iProgressLabelLen) + 4 - (size_t)bufptr % 4); memset(bufptr, 0, 4 - (size_t)bufptr % 4); //suppress valgrind warning "uninitialized data" bufptr += 4 - (size_t)bufptr % 4; } } g_pQueueCoordinator->UnlockQueue(); PostQueueResponse.m_iNrTrailingEntries = htonl(NrEntries); PostQueueResponse.m_iTrailingDataLength = htonl(bufsize); // Send the request answer send(m_iSocket, (char*) &PostQueueResponse, sizeof(PostQueueResponse), 0); // Send the data if (bufsize > 0) { send(m_iSocket, buf, bufsize, 0); } free(buf); }