summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2017-08-08 14:49:49 +0200
committerUlf Hermann <ulf.hermann@qt.io>2017-08-08 13:58:36 +0000
commita028f6717f0e183f3a16361c9b07b190edac57b3 (patch)
tree0e78c81498f175b00b6588250fbe2d60c3898de6
parent8b5582c4248d8c06eb3a39127fdf0580bf2de5d0 (diff)
downloadqt-creator-a028f6717f0e183f3a16361c9b07b190edac57b3.tar.gz
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 <hjk@qt.io>
-rw-r--r--src/plugins/projectexplorer/runconfiguration.cpp132
-rw-r--r--src/plugins/projectexplorer/runconfiguration.h1
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> runControl;
QList<RunWorker *> startDependencies;
+ QList<RunWorker *> 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);