forked from qt-creator/qt-creator
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 <christian.stenger@qt.io>
This commit is contained in:
@@ -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;
|
||||
|
Reference in New Issue
Block a user