void JobManager::DoSchedule(InternalJob::Pointer job, Poco::Timestamp::TimeDiff delay) { Poco::ScopedLock<Poco::Mutex> managerLock(m_mutex); //job may have been canceled already int state = job->InternalGetState(); if (state != InternalJob::ABOUT_TO_SCHEDULE && state != Job::SLEEPING) return; //if it's a decoration job with no rule, don't run it right now if the system is busy if (job->GetPriority() == Job::DECORATE && job->GetRule() == 0) { Poco::Timestamp::TimeDiff tmp_minDelay = m_running.size() * 100; delay = std::max(delay, tmp_minDelay); } if (delay > 0) { job->SetStartTime(Poco::Timestamp() + delay * 100); InternalJob::Pointer sptr_job(job); ChangeState(sptr_job, Job::SLEEPING); } else { job->SetStartTime(Poco::Timestamp() + DelayFor(job->GetPriority()) * 100); job->SetWaitQueueStamp(m_waitQueueCounter++); InternalJob::Pointer sptr_job(job); ChangeState(sptr_job, Job::WAITING); } }
bool JobManager::IsBlocking(InternalJob::Pointer sptr_runningJob) { { Poco::ScopedLock<Poco::Mutex> lockMe (m_mutex); // if this job isn't running, it can't be blocking anyone if (sptr_runningJob->GetState() != Job::RUNNING) return false; // if any job is queued behind this one, it is blocked by it InternalJob::Pointer ptr_previous = sptr_runningJob->Previous(); while (ptr_previous != 0) { // ignore jobs of lower priority (higher priority value means lower priority) if (ptr_previous->GetPriority() < sptr_runningJob->GetPriority()) { if (!ptr_previous->IsSystem()) return true; // TODO Implicit Jobs // implicit jobs should interrupt unless they act on behalf of system jobs // if (previous instanceof ThreadJob && ((ThreadJob) previous).shouldInterrupt()) // return true; } ptr_previous = ptr_previous->previous; } // none found return false; } }
void JobManager::SetPriority(InternalJob::Pointer job, int newPriority) { { Poco::ScopedLock<Poco::Mutex> lockMe (m_mutex); InternalJob::Pointer sptr_job(job); int oldPriority = job->GetPriority(); if (oldPriority == newPriority) return; job->InternalSetPriority(newPriority); //if the job is waiting to run, re-shuffle the queue if (sptr_job->GetState() == Job::WAITING) { Poco::Timestamp oldStart = job->GetStartTime(); job->SetStartTime(oldStart += (DelayFor(newPriority) - DelayFor(oldPriority))); m_JobQueueWaiting.Resort(job); } } }