예제 #1
0
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);
}
예제 #2
0
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());
}
예제 #3
0
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();
}
예제 #4
0
파일: BinRpc.cpp 프로젝트: Bootz/nzbm
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);
}