From a028f6717f0e183f3a16361c9b07b190edac57b3 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Tue, 8 Aug 2017 14:49:49 +0200 Subject: ProjectExplorer: Add stop dependencies for RunWorkers A run worker will only be stopped if all its stop dependencies are stopped. Change-Id: I16a42253874adafb9ca87d175bfb361fae46cc39 Reviewed-by: hjk --- src/plugins/projectexplorer/runconfiguration.cpp | 132 +++++++++++------------ src/plugins/projectexplorer/runconfiguration.h | 1 + 2 files changed, 66 insertions(+), 67 deletions(-) diff --git a/src/plugins/projectexplorer/runconfiguration.cpp b/src/plugins/projectexplorer/runconfiguration.cpp index 740fd8ebbb..e1563957d6 100644 --- a/src/plugins/projectexplorer/runconfiguration.cpp +++ b/src/plugins/projectexplorer/runconfiguration.cpp @@ -532,12 +532,14 @@ public: RunWorkerPrivate(RunWorker *runWorker, RunControl *runControl); bool canStart() const; + bool canStop() const; void timerEvent(QTimerEvent *ev) override; RunWorker *q; RunWorkerState state = RunWorkerState::Initialized; QPointer runControl; QList startDependencies; + QList stopDependencies; QString id; QVariantMap data; @@ -612,6 +614,7 @@ public: void initiateReStart(); void continueStart(); void initiateStop(); + void continueStopOrFinish(); void initiateFinish(); void onWorkerStarted(RunWorker *worker); @@ -833,7 +836,23 @@ void RunControlPrivate::initiateStop() setState(RunControlState::Stopping); debugMessage("Queue: Stopping for all workers"); + continueStopOrFinish(); +} + +void RunControlPrivate::continueStopOrFinish() +{ bool allDone = true; + + auto queueStop = [this](RunWorker *worker, const QString &message) { + if (worker->d->canStop()) { + debugMessage(message); + worker->d->state = RunWorkerState::Stopping; + QTimer::singleShot(0, worker, &RunWorker::initiateStop); + } else { + debugMessage(" " + worker->d->id + " is waiting for dependent workers to stop"); + } + }; + for (RunWorker *worker : m_workers) { if (worker) { const QString &workerId = worker->d->id; @@ -848,16 +867,12 @@ void RunControlPrivate::initiateStop() allDone = false; break; case RunWorkerState::Starting: - debugMessage(" " + workerId + " was Starting, queuing stop"); - worker->d->state = RunWorkerState::Stopping; - QTimer::singleShot(0, worker, &RunWorker::initiateStop); + queueStop(worker, " " + workerId + " was Starting, queuing stop"); allDone = false; break; case RunWorkerState::Running: - debugMessage(" " + workerId + " was Running, queuing stop"); - worker->d->state = RunWorkerState::Stopping; + queueStop(worker, " " + workerId + " was Running, queuing stop"); allDone = false; - QTimer::singleShot(0, worker, &RunWorker::initiateStop); break; case RunWorkerState::Done: debugMessage(" " + workerId + " was Done. Good."); @@ -870,11 +885,20 @@ void RunControlPrivate::initiateStop() debugMessage("Found unknown deleted worker"); } } + + RunControlState targetState; + if (state == RunControlState::Finishing) { + targetState = RunControlState::Finished; + } else { + checkState(RunControlState::Stopping); + targetState = RunControlState::Stopped; + } + if (allDone) { - debugMessage("All stopped."); - setState(RunControlState::Stopped); + debugMessage("All Stopped"); + setState(targetState); } else { - debugMessage("Not all workers stopped. Waiting..."); + debugMessage("Not all workers Stopped. Waiting..."); } } @@ -883,48 +907,7 @@ void RunControlPrivate::initiateFinish() setState(RunControlState::Finishing); debugMessage("Ramping down"); - bool allDone = true; - for (RunWorker *worker : m_workers) { - if (worker) { - const QString &workerId = worker->d->id; - debugMessage(" Examining worker " + workerId); - switch (worker->d->state) { - case RunWorkerState::Initialized: - debugMessage(" " + workerId + " was Initialized, setting to Done"); - worker->d->state = RunWorkerState::Done; - break; - case RunWorkerState::Stopping: - debugMessage(" " + workerId + " was already Stopping. Keeping it that way"); - allDone = false; - break; - case RunWorkerState::Starting: - debugMessage(" " + workerId + " was Starting, queuing stop"); - worker->d->state = RunWorkerState::Stopping; - QTimer::singleShot(0, worker, &RunWorker::initiateStop); - allDone = false; - break; - case RunWorkerState::Running: - debugMessage(" " + workerId + " was Running, queuing stop"); - worker->d->state = RunWorkerState::Stopping; - allDone = false; - QTimer::singleShot(0, worker, &RunWorker::initiateStop); - break; - case RunWorkerState::Done: - debugMessage(" " + workerId + " was Done. Good."); - break; - case RunWorkerState::Failed: - debugMessage(" " + workerId + " was Failed. Good"); - break; - } - } else { - debugMessage("Found unknown deleted worker"); - } - } - if (allDone) { - setState(RunControlState::Finished); - } else { - debugMessage("Not all workers finished. Waiting..."); - } + continueStopOrFinish(); } void RunControlPrivate::onWorkerStarted(RunWorker *worker) @@ -973,6 +956,11 @@ void RunControlPrivate::onWorkerStopped(RunWorker *worker) break; } + if (state == RunControlState::Finishing || state == RunControlState::Stopping) { + continueStopOrFinish(); + return; + } + debugMessage("Checking whether all stopped"); bool allDone = true; for (RunWorker *worker : m_workers) { @@ -1006,24 +994,16 @@ void RunControlPrivate::onWorkerStopped(RunWorker *worker) debugMessage("Found unknown deleted worker"); } } - if (state == RunControlState::Finishing) { - if (allDone) { - debugMessage("All finished. Deleting myself"); - setState(RunControlState::Finished); + + if (allDone) { + if (state == RunControlState::Stopped) { + debugMessage("All workers stopped, but runControl was already stopped."); } else { - debugMessage("Not all workers finished. Waiting..."); + debugMessage("All workers stopped. Set runControl to Stopped"); + setState(RunControlState::Stopped); } } else { - if (allDone) { - if (state == RunControlState::Stopped) { - debugMessage("All workers stopped, but runControl was already stopped."); - } else { - debugMessage("All workers stopped. Set runControl to Stopped"); - setState(RunControlState::Stopped); - } - } else { - debugMessage("Not all workers stopped. Waiting..."); - } + debugMessage("Not all workers stopped. Waiting..."); } } @@ -1456,7 +1436,7 @@ bool RunWorkerPrivate::canStart() const if (state != RunWorkerState::Initialized) return false; for (RunWorker *worker : startDependencies) { - QTC_ASSERT(worker, return true); + QTC_ASSERT(worker, continue); if (worker->d->state != RunWorkerState::Done && worker->d->state != RunWorkerState::Running) return false; @@ -1464,6 +1444,19 @@ bool RunWorkerPrivate::canStart() const return true; } +bool RunWorkerPrivate::canStop() const +{ + if (state != RunWorkerState::Starting && state != RunWorkerState::Running) + return false; + for (RunWorker *worker : stopDependencies) { + QTC_ASSERT(worker, continue); + if (worker->d->state != RunWorkerState::Done + && worker->d->state != RunWorkerState::Failed) + return false; + } + return true; +} + void RunWorkerPrivate::timerEvent(QTimerEvent *ev) { if (ev->timerId() == startWatchdogTimerId) { @@ -1623,6 +1616,11 @@ void RunWorker::addStartDependency(RunWorker *dependency) d->startDependencies.append(dependency); } +void RunWorker::addStopDependency(RunWorker *dependency) +{ + d->stopDependencies.append(dependency); +} + RunControl *RunWorker::runControl() const { return d->runControl; diff --git a/src/plugins/projectexplorer/runconfiguration.h b/src/plugins/projectexplorer/runconfiguration.h index c9f3fae9be..d905e66872 100644 --- a/src/plugins/projectexplorer/runconfiguration.h +++ b/src/plugins/projectexplorer/runconfiguration.h @@ -323,6 +323,7 @@ public: RunControl *runControl() const; void addStartDependency(RunWorker *dependency); + void addStopDependency(RunWorker *dependency); void setDisplayName(const QString &id) { setId(id); } // FIXME: Obsoleted by setId. void setId(const QString &id); -- cgit v1.2.1