// FinalizeCompletedJobs (Main Thread) //------------------------------------------------------------------------------ void JobQueue::FinalizeCompletedJobs() { { MutexHolder m( m_CompletedJobsMutex ); m_CompletedJobs2.Swap( m_CompletedJobs ); m_CompletedJobsFailed2.Swap( m_CompletedJobsFailed ); } // completed jobs const Job * const * end = m_CompletedJobs2.End(); for ( Job ** i = m_CompletedJobs2.Begin(); i != end; i++ ) { Job * job = ( *i ); Node * n = job->GetNode(); if ( n->Finalize() ) { n->SetState( Node::UP_TO_DATE ); } else { n->SetState( Node::FAILED ); } FDELETE job; } m_CompletedJobs2.Clear(); // failed jobs end = m_CompletedJobsFailed2.End(); for ( Job ** i = m_CompletedJobsFailed2.Begin(); i != end; i++ ) { Job * job = ( *i ); job->GetNode()->SetState( Node::FAILED ); FDELETE job; } m_CompletedJobsFailed2.Clear(); }
// GetCompletedJob //------------------------------------------------------------------------------ Job * JobQueueRemote::GetCompletedJob() { MutexHolder m( m_CompletedJobsMutex ); // completed jobs if ( !m_CompletedJobs.IsEmpty() ) { Job * job = m_CompletedJobs[ 0 ]; m_CompletedJobs.PopFront(); job->GetNode()->SetState( Node::UP_TO_DATE ); return job; } // failed jobs if ( !m_CompletedJobsFailed.IsEmpty() ) { Job * job = m_CompletedJobsFailed[ 0 ]; m_CompletedJobsFailed.PopFront(); job->GetNode()->SetState( Node::FAILED ); return job; } return nullptr; }
// Update //------------------------------------------------------------------------------ /*static*/ bool WorkerThread::Update() { // try to find some work to do Job * job = JobQueue::IsValid() ? JobQueue::Get().GetJobToProcess() : nullptr; if ( job != nullptr ) { // make sure state is as expected ASSERT( job->GetNode()->GetState() == Node::BUILDING ); // process the work Node::BuildResult result = JobQueue::DoBuild( job ); if ( result == Node::NODE_RESULT_FAILED ) { FBuild::OnBuildError(); } if ( result == Node::NODE_RESULT_NEED_SECOND_BUILD_PASS ) { JobQueue::Get().QueueJob2( job ); } else { JobQueue::Get().FinishedProcessingJob( job, ( result != Node::NODE_RESULT_FAILED ), false, false ); } return true; // did some work } // no local job, see if we can do one from the remote queue if ( FBuild::Get().GetOptions().m_NoLocalConsumptionOfRemoteJobs == false ) { job = JobQueue::IsValid() ? JobQueue::Get().GetDistributableJobToProcess( false ) : nullptr; if ( job != nullptr ) { // process the work Node::BuildResult result = JobQueueRemote::DoBuild( job, false ); if ( result == Node::NODE_RESULT_FAILED ) { FBuild::OnBuildError(); } JobQueue::Get().FinishedProcessingJob( job, ( result != Node::NODE_RESULT_FAILED ), true, false ); // returning a remote job, not a local race return true; // did some work } } // race remote jobs if ( FBuild::Get().GetOptions().m_AllowLocalRace ) { job = JobQueue::IsValid() ? JobQueue::Get().GetDistributableJobToRace() : nullptr; if ( job != nullptr ) { // process the work Node::BuildResult result = JobQueueRemote::DoBuild( job, true ); if ( result == Node::NODE_RESULT_FAILED ) { FBuild::OnBuildError(); } JobQueue::Get().FinishedProcessingJob( job, ( result != Node::NODE_RESULT_FAILED ), true, true ); // returning a remote job, local race return true; // did some work } } return false; // no work to do }