Commit 7f2cb9ea authored by hjk's avatar hjk

ProjectExplorer: Allow user stopping ill-behaved RunControl

If a RunWorker fails to report success or failure (should not happen in
theory, but has been observed in practice, typically in exceptional code
paths) the RunControl will stay in 'Starting' or 'Stopping' state
forever. Give the user the opportunity to force a 'Stopped' state by a
second (or when 'Running' a third) time on the Stop button.

Change-Id: Iec58434927777bd67bfe01c5144ee5695b4d6cf1
Reviewed-by: Christian Stenger's avatarChristian Stenger <christian.stenger@qt.io>
parent 89d08bf4
......@@ -534,9 +534,9 @@ void AppOutputPane::stopRunControl()
if (rc->isRunning() && optionallyPromptToStop(rc))
rc->initiateStop();
else if (rc->isStarting()) {
else {
QTC_CHECK(false);
rc->initiateStop();
rc->forceStop();
}
if (debug)
......
......@@ -640,6 +640,7 @@ public:
void initiateReStart();
void continueStart();
void initiateStop();
void forceStop();
void continueStopOrFinish();
void initiateFinish();
......@@ -724,6 +725,11 @@ void RunControl::initiateStop()
d->initiateStop();
}
void RunControl::forceStop()
{
d->forceStop();
}
void RunControl::initiateFinish()
{
QTimer::singleShot(0, d, &RunControlPrivate::initiateFinish);
......@@ -921,6 +927,43 @@ void RunControlPrivate::continueStopOrFinish()
}
}
void RunControlPrivate::forceStop()
{
if (state == RunControlState::Finished) {
debugMessage("Was finished, too late to force Stop");
return;
}
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");
break;
case RunWorkerState::Stopping:
debugMessage(" " + workerId + " was already Stopping. Set it forcefully to Done.");
break;
case RunWorkerState::Starting:
debugMessage(" " + workerId + " was Starting. Set it forcefully to Done.");
break;
case RunWorkerState::Running:
debugMessage(" " + workerId + " was Running. Set it forcefully to Done.");
break;
case RunWorkerState::Done:
debugMessage(" " + workerId + " was Done. Good.");
break;
}
worker->d->state = RunWorkerState::Done;
} else {
debugMessage("Found unknown deleted worker");
}
}
setState(RunControlState::Stopped);
debugMessage("All Stopped");
}
void RunControlPrivate::initiateFinish()
{
setState(RunControlState::Finishing);
......
......@@ -411,6 +411,7 @@ public:
void initiateStart();
void initiateReStart();
void initiateStop();
void forceStop();
void initiateFinish();
bool promptToStop(bool *optionalPrompt = nullptr) const;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment