예제 #1
0
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;
  }
}
예제 #2
0
void JobQueue::Enqueue(InternalJob::Pointer newEntry)
{
  InternalJob::Pointer tail = dummy->Next();
  //overtake lower priority jobs. Only overtake conflicting jobs if allowed to
  while (CanOvertake(newEntry, tail))
    tail = tail->Next();
  InternalJob::Pointer tailPrevious = tail->Previous();
  newEntry->SetNext(tail);
  newEntry->SetPrevious(tailPrevious);
  tailPrevious->SetNext(newEntry);
  tail->SetPrevious(newEntry);

}
예제 #3
0
void JobManager::ChangeState(InternalJob::Pointer sptr_job, int newState)
{

  bool blockedJobs = false;
  {
    Poco::ScopedLock<Poco::Mutex> m_managerLock(m_mutex);

    int tmp_oldState = sptr_job->InternalGetState();
    switch (tmp_oldState)
    {
    case Job::NONE:

    case InternalJob::ABOUT_TO_SCHEDULE:
      break;
    case InternalJob::BLOCKED:
      //remove this job from the linked list of blocked jobs
      sptr_job->Remove();
      break;
    case Job::WAITING:
      m_JobQueueWaiting.Remove(sptr_job);

      // assert(false, "Tried to remove a job that wasn't in the queue");
      break;
    case Job::SLEEPING:
      m_JobQueueSleeping.Remove(sptr_job);
      // assert(false, "Tried to remove a job that wasn't in the queue");

    case Job::RUNNING:
    case InternalJob::ABOUT_TO_RUN:
      m_running.remove(sptr_job);
      //add any blocked jobs back to the wait queue
      InternalJob::Pointer sptr_blocked(sptr_job->Previous());
      sptr_job->Remove();
      blockedJobs = sptr_blocked != 0;
      while (sptr_blocked != 0)
      {
        InternalJob::Pointer previous = sptr_blocked->Previous();
        ChangeState(sptr_blocked, Job::WAITING);
        sptr_blocked = previous;
      }
      break;
      // default :
      // Assert.isLegal(false, "Invalid job state: " + job + ", state: " + oldState);
    }

    sptr_job->InternalSetState(newState);
    switch (newState)
    {
    case Job::NONE:
      sptr_job->SetStartTime(InternalJob::T_NONE);
      sptr_job->SetWaitQueueStamp(InternalJob::T_NONE);
    case InternalJob::BLOCKED:
      break;
    case Job::WAITING:
      m_JobQueueWaiting.Enqueue(sptr_job);
      break;
    case Job::SLEEPING:
      //try {
      m_JobQueueSleeping.Enqueue(sptr_job);
      //} catch (RuntimeException e) {
      //  throw new RuntimeException("Error changing from state: " + oldState);
      //}
      break;
    case Job::RUNNING:
    case InternalJob::ABOUT_TO_RUN:
      sptr_job->SetStartTime(InternalJob::T_NONE);
      sptr_job->SetWaitQueueStamp(InternalJob::T_NONE);
      m_running.insert(sptr_job);
      break;
    case InternalJob::ABOUT_TO_SCHEDULE:
      break;
      //  default :
      //    Assert.isLegal(false, "Invalid job state: " + job + ", state: " + newState);
    }
  }

  //notify queue outside sync block
  if (blockedJobs)
    m_Pool->JobQueued();
}