void JobManager::EndJob(InternalJob::Pointer ptr_job, IStatus::Pointer result, bool notify) { Poco::Timestamp::TimeDiff rescheduleDelay(InternalJob::T_NONE); { Poco::ScopedLock<Poco::Mutex> lock ( m_mutex); // if the job is finishing asynchronously, there is nothing more to do for now if (result == Job::ASYNC_FINISH) return; //if job is not known then it cannot be done if (ptr_job->GetState() == Job::NONE) return; ptr_job->SetResult(result); ptr_job->SetProgressMonitor(IProgressMonitor::Pointer(nullptr)); ptr_job->SetThread(nullptr); rescheduleDelay = ptr_job->GetStartTime().epochMicroseconds(); InternalJob::Pointer sptr_job(ptr_job); ChangeState(sptr_job, Job::NONE); } //notify listeners outside sync block bool reschedule = m_active && rescheduleDelay > InternalJob::T_NONE && ptr_job->ShouldSchedule(); if (notify) m_JobListeners.Done(ptr_job.Cast<Job>(), result, reschedule); //reschedule the job if requested and we are still active if (reschedule) Schedule(ptr_job, rescheduleDelay, reschedule); }
bool JobManager::RunNow(InternalJob::Pointer sptr_job) { { Poco::ScopedLock<Poco::Mutex> lockMe (m_mutex); //cannot start if there is a conflicting job if (FindBlockingJob(sptr_job) != 0) return false; ChangeState(sptr_job, Job::RUNNING); sptr_job->SetProgressMonitor(IProgressMonitor::Pointer(new NullProgressMonitor())); sptr_job->Run(IProgressMonitor::Pointer(nullptr)); } return true; }
Job::Pointer JobManager::StartJob() { Job::Pointer job(nullptr); while (true) { job = NextJob(); if (!job) return Job::Pointer(nullptr); //must perform this outside sync block because it is third party code bool shouldRun = job->ShouldRun(); //check for listener veto if (shouldRun) m_JobListeners.AboutToRun(job); //listeners may have canceled or put the job to sleep bool endJob = false; { Poco::ScopedLock<Poco::Mutex> lock(m_mutex); InternalJob::Pointer internal = job; if (internal->InternalGetState() == InternalJob::ABOUT_TO_RUN) { if (shouldRun && !internal->IsAboutToRunCanceled()) { internal->SetProgressMonitor(CreateMonitor(job)); //change from ABOUT_TO_RUN to RUNNING internal->InternalSetState(Job::RUNNING); break; } internal->SetAboutToRunCanceled(false); endJob = true; //fall through and end the job below } } if (endJob) { //job has been vetoed or canceled, so mark it as done EndJob(job,Status::CANCEL_STATUS(BERRY_STATUS_LOC), true); continue; } } m_JobListeners.Running(job); return job; }