From 4605febacfbad61b13dd93e4f599884e2c38f886 Mon Sep 17 00:00:00 2001 From: Rene Gollent Date: Sun, 1 Dec 2013 21:10:51 -0500 Subject: [PATCH] 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. --- src/apps/debugger/util/Worker.cpp | 51 +++++++++++++++++++++++++++++-- src/apps/debugger/util/Worker.h | 12 +++++++- 2 files changed, 59 insertions(+), 4 deletions(-) diff --git a/src/apps/debugger/util/Worker.cpp b/src/apps/debugger/util/Worker.cpp index 304c3bd033..e395af4dbc 100644 --- a/src/apps/debugger/util/Worker.cpp +++ b/src/apps/debugger/util/Worker.cpp @@ -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. * 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 Job::SetWorker(Worker* worker) { @@ -141,6 +148,7 @@ Job::SetWaitStatus(job_wait_status status) fWaitStatus = status; switch (fWaitStatus) { case JOB_DEPENDENCY_ACTIVE: + case JOB_USER_INPUT_WAITING: fState = JOB_STATE_WAITING; break; default: @@ -315,6 +323,25 @@ Worker::GetJob(const JobKey& key) } +status_t +Worker::ResumeJob(Job* job) +{ + AutoLocker 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 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 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 Worker::_WorkerLoopEntry(void* data) { @@ -439,10 +481,13 @@ Worker::_AbortJob(Job* job, bool removeFromTable) break; case JOB_STATE_WAITING: - job->Dependency()->DependentJobs().Remove(job); + { + 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: diff --git a/src/apps/debugger/util/Worker.h b/src/apps/debugger/util/Worker.h index 411b9cba03..f3fa550a20 100644 --- a/src/apps/debugger/util/Worker.h +++ b/src/apps/debugger/util/Worker.h @@ -1,5 +1,6 @@ /* * Copyright 2009-2012, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2014, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ #ifndef WORKER_H @@ -31,7 +32,9 @@ enum job_wait_status { JOB_DEPENDENCY_SUCCEEDED, JOB_DEPENDENCY_FAILED, JOB_DEPENDENCY_ABORTED, - JOB_DEPENDENCY_ACTIVE + JOB_DEPENDENCY_ACTIVE, + + JOB_USER_INPUT_WAITING // internal only }; @@ -88,6 +91,7 @@ public: protected: job_wait_status WaitFor(const JobKey& key); + status_t WaitForUserInput(); private: friend class Worker; @@ -141,6 +145,10 @@ public: void AbortJob(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, JobListener* listener); void RemoveListener(const JobKey& key, @@ -178,6 +186,7 @@ private: private: job_wait_status WaitForJob(Job* waitingJob, const JobKey& key); + status_t WaitForUserInput(Job* waitingJob); static status_t _WorkerLoopEntry(void* data); status_t _WorkerLoop(); @@ -191,6 +200,7 @@ private: JobTable fJobs; JobList fUnscheduledJobs; JobList fAbortedJobs; + JobList fSuspendedJobs; sem_id fWorkToDoSem; thread_id fWorkerThread; volatile bool fTerminating;