Debugger: Add/handle new suspend state for jobs.

- In addition to waiting for one or more dependent jobs to complete,
a job can now potentially wait for user input to proceed further. Add
a corresponding job_wait_status and respective handling in Worker.
This commit is contained in:
Rene Gollent 2013-12-01 21:10:51 -05:00
parent 004f41565e
commit 4605febacf
2 changed files with 59 additions and 4 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2012, Rene Gollent, rene@gollent.com. * Copyright 2012-2014, Rene Gollent, rene@gollent.com.
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
@ -114,6 +114,13 @@ Job::WaitFor(const JobKey& key)
} }
status_t
Job::WaitForUserInput()
{
return fWorker->WaitForUserInput(this);
}
void void
Job::SetWorker(Worker* worker) Job::SetWorker(Worker* worker)
{ {
@ -141,6 +148,7 @@ Job::SetWaitStatus(job_wait_status status)
fWaitStatus = status; fWaitStatus = status;
switch (fWaitStatus) { switch (fWaitStatus) {
case JOB_DEPENDENCY_ACTIVE: case JOB_DEPENDENCY_ACTIVE:
case JOB_USER_INPUT_WAITING:
fState = JOB_STATE_WAITING; fState = JOB_STATE_WAITING;
break; break;
default: default:
@ -315,6 +323,25 @@ Worker::GetJob(const JobKey& key)
} }
status_t
Worker::ResumeJob(Job* job)
{
AutoLocker<Worker> locker(this);
for (JobList::Iterator it = fSuspendedJobs.GetIterator(); it.Next();) {
if (it.Current() == job) {
it.Remove();
job->SetState(JOB_STATE_UNSCHEDULED);
fUnscheduledJobs.Add(job);
release_sem(fWorkToDoSem);
return B_OK;
}
}
return B_ENTRY_NOT_FOUND;
}
status_t status_t
Worker::AddListener(const JobKey& key, JobListener* listener) Worker::AddListener(const JobKey& key, JobListener* listener)
{ {
@ -359,6 +386,21 @@ Worker::WaitForJob(Job* waitingJob, const JobKey& key)
} }
status_t
Worker::WaitForUserInput(Job* waitingJob)
{
AutoLocker<Worker> locker(this);
if (fTerminating || waitingJob->State() == JOB_STATE_ABORTED)
return B_INTERRUPTED;
waitingJob->SetWaitStatus(JOB_USER_INPUT_WAITING);
fSuspendedJobs.Add(waitingJob);
return B_OK;
}
/*static*/ status_t /*static*/ status_t
Worker::_WorkerLoopEntry(void* data) Worker::_WorkerLoopEntry(void* data)
{ {
@ -439,10 +481,13 @@ Worker::_AbortJob(Job* job, bool removeFromTable)
break; break;
case JOB_STATE_WAITING: case JOB_STATE_WAITING:
job->Dependency()->DependentJobs().Remove(job); {
Job* dependency = job->Dependency();
if (dependency != NULL)
dependency->DependentJobs().Remove(job);
job->SetDependency(NULL); job->SetDependency(NULL);
break; break;
}
case JOB_STATE_ACTIVE: case JOB_STATE_ACTIVE:
case JOB_STATE_FAILED: case JOB_STATE_FAILED:
case JOB_STATE_SUCCEEDED: case JOB_STATE_SUCCEEDED:

View File

@ -1,5 +1,6 @@
/* /*
* Copyright 2009-2012, Ingo Weinhold, ingo_weinhold@gmx.de. * Copyright 2009-2012, Ingo Weinhold, ingo_weinhold@gmx.de.
* Copyright 2014, Rene Gollent, rene@gollent.com.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
#ifndef WORKER_H #ifndef WORKER_H
@ -31,7 +32,9 @@ enum job_wait_status {
JOB_DEPENDENCY_SUCCEEDED, JOB_DEPENDENCY_SUCCEEDED,
JOB_DEPENDENCY_FAILED, JOB_DEPENDENCY_FAILED,
JOB_DEPENDENCY_ABORTED, JOB_DEPENDENCY_ABORTED,
JOB_DEPENDENCY_ACTIVE JOB_DEPENDENCY_ACTIVE,
JOB_USER_INPUT_WAITING
// internal only // internal only
}; };
@ -88,6 +91,7 @@ public:
protected: protected:
job_wait_status WaitFor(const JobKey& key); job_wait_status WaitFor(const JobKey& key);
status_t WaitForUserInput();
private: private:
friend class Worker; friend class Worker;
@ -141,6 +145,10 @@ public:
void AbortJob(const JobKey& key); void AbortJob(const JobKey& key);
Job* GetJob(const JobKey& key); Job* GetJob(const JobKey& key);
status_t ResumeJob(Job* job);
// only valid for jobs that are
// suspended pending user input
status_t AddListener(const JobKey& key, status_t AddListener(const JobKey& key,
JobListener* listener); JobListener* listener);
void RemoveListener(const JobKey& key, void RemoveListener(const JobKey& key,
@ -178,6 +186,7 @@ private:
private: private:
job_wait_status WaitForJob(Job* waitingJob, const JobKey& key); job_wait_status WaitForJob(Job* waitingJob, const JobKey& key);
status_t WaitForUserInput(Job* waitingJob);
static status_t _WorkerLoopEntry(void* data); static status_t _WorkerLoopEntry(void* data);
status_t _WorkerLoop(); status_t _WorkerLoop();
@ -191,6 +200,7 @@ private:
JobTable fJobs; JobTable fJobs;
JobList fUnscheduledJobs; JobList fUnscheduledJobs;
JobList fAbortedJobs; JobList fAbortedJobs;
JobList fSuspendedJobs;
sem_id fWorkToDoSem; sem_id fWorkToDoSem;
thread_id fWorkerThread; thread_id fWorkerThread;
volatile bool fTerminating; volatile bool fTerminating;