void Worker::_AbortJob(Job* job, bool removeFromTable) { switch (job->State()) { case JOB_STATE_ABORTED: return; case JOB_STATE_UNSCHEDULED: fUnscheduledJobs.Remove(job); fAbortedJobs.Add(job); break; case JOB_STATE_WAITING: { Job* dependency = job->Dependency(); if (dependency != NULL) dependency->DependentJobs().Remove(job); job->SetDependency(NULL); break; } case JOB_STATE_ACTIVE: case JOB_STATE_FAILED: case JOB_STATE_SUCCEEDED: default: break; } job->SetState(JOB_STATE_ABORTED); if (removeFromTable) fJobs.Remove(job); }
job_wait_status Worker::WaitForJob(Job* waitingJob, const JobKey& key) { AutoLocker<Worker> locker(this); // don't wait when the game is over anyway if (fTerminating || waitingJob->State() == JOB_STATE_ABORTED) return JOB_DEPENDENCY_ABORTED; Job* job = fJobs.Lookup(key); if (job == NULL) return JOB_DEPENDENCY_NOT_FOUND; waitingJob->SetWaitStatus(JOB_DEPENDENCY_ACTIVE); waitingJob->SetDependency(job); job->DependentJobs().Add(waitingJob); // TODO: Continuations would be nice. For the time being we have to use // recursion. Disadvantages are that we'll use more stack and that aborting // a job waiting for a dependency won't abort the job before the dependency // is done. locker.Unlock(); _ProcessJobs(waitingJob); locker.Lock(); // ignore the actual wait status when the game is over anyway if (fTerminating || waitingJob->State() == JOB_STATE_ABORTED) return JOB_DEPENDENCY_ABORTED; return waitingJob->WaitStatus(); }
job_wait_status Worker::WaitForJob(Job* waitingJob, const JobKey& key) { AutoLocker<Worker> locker(this); // don't wait when the game is over anyway if (fTerminating || waitingJob->State() == JOB_STATE_ABORTED) return JOB_DEPENDENCY_ABORTED; Job* job = fJobs.Lookup(key); if (job == NULL) return JOB_DEPENDENCY_NOT_FOUND; waitingJob->SetWaitStatus(JOB_DEPENDENCY_ACTIVE); waitingJob->SetDependency(job); job->DependentJobs().Add(waitingJob); return waitingJob->WaitStatus(); }