Commit 48b2af5e authored by Christian Stenger's avatar Christian Stenger

AutoTest: Cancel possible running tasks on shutdown

If tasks are running while shutting down we might end up in a crash,
so cancel all tasks and handle possible invalid accesses of the
current running processing.

Change-Id: I69f7cac5f44390e322fa301af6d6794270c95c2a
Reviewed-by: Eike Ziller's avatarEike Ziller <eike.ziller@qt.io>
parent e70adf82
......@@ -154,6 +154,7 @@ void AutotestPlugin::extensionsInitialized()
ExtensionSystem::IPlugin::ShutdownFlag AutotestPlugin::aboutToShutdown()
{
TestTreeModel::instance()->parser()->aboutToShutdown();
return SynchronousShutdown;
}
......
......@@ -90,6 +90,8 @@ static bool handleGTest(QFutureInterface<TestParseResultPtr> futureInterface,
const QList<CppTools::ProjectPart::Ptr> &ppList = modelManager->projectPart(filePath);
if (ppList.size())
proFile = ppList.first()->projectFile;
else
return false; // happens if shutting down while parsing
foreach (const GTestCaseSpec &testSpec, result.keys()) {
GTestParseResult *parseResult = new GTestParseResult(id);
......
......@@ -199,7 +199,10 @@ static bool handleQtTest(QFutureInterface<TestParseResultPtr> futureInterface,
parseResult->displayName = testCaseName;
parseResult->line = line;
parseResult->column = column;
parseResult->proFile = modelManager->projectPart(fileName).first()->projectFile;
QList<CppTools::ProjectPart::Ptr> projectParts = modelManager->projectPart(fileName);
if (projectParts.isEmpty()) // happens if shutting down while parsing
return false;
parseResult->proFile = projectParts.first()->projectFile;
QMap<QString, TestCodeLocationAndType>::ConstIterator it = testFunctions.begin();
const QMap<QString, TestCodeLocationAndType>::ConstIterator end = testFunctions.end();
for ( ; it != end; ++it) {
......
......@@ -202,7 +202,8 @@ static bool handleQtQuickTest(QFutureInterface<TestParseResultPtr> futureInterfa
const QString cppFileName = document->fileName();
QList<CppTools::ProjectPart::Ptr> ppList = modelManager->projectPart(cppFileName);
QTC_ASSERT(!ppList.isEmpty(), return false);
if (ppList.isEmpty()) // happens if shutting down while parsing
return false;
const QString &proFile = ppList.at(0)->projectFile;
const QString srcDir = quickTestSrcDir(modelManager, cppFileName);
......
......@@ -85,6 +85,8 @@ TestCodeParser::~TestCodeParser()
void TestCodeParser::setState(State state)
{
if (m_parserState == Shutdown)
return;
qCDebug(LOG) << "setState(" << state << "), currentState:" << m_parserState;
// avoid triggering parse before code model parsing has finished, but mark as dirty
if (m_codeModelParsing) {
......@@ -175,6 +177,8 @@ static bool checkDocumentForTestCode(QFutureInterface<TestParseResultPtr> &futur
const QVector<ITestParser *> &parsers)
{
foreach (ITestParser *currentParser, parsers) {
if (futureInterface.isCanceled())
return false;
if (currentParser->processDocument(futureInterface, fileName))
return true;
}
......@@ -253,6 +257,17 @@ void TestCodeParser::onProjectPartsUpdated(ProjectExplorer::Project *project)
emitUpdateTestTree();
}
void TestCodeParser::aboutToShutdown()
{
qCDebug(LOG) << "Disabling (immediately) - shutting down";
State oldState = m_parserState;
m_parserState = Shutdown;
if (oldState == PartialParse || oldState == FullParse) {
m_futureWatcher.cancel();
m_futureWatcher.waitForFinished();
}
}
bool TestCodeParser::postponed(const QStringList &fileList)
{
switch (m_parserState) {
......@@ -278,6 +293,7 @@ bool TestCodeParser::postponed(const QStringList &fileList)
}
return true;
case Disabled:
case Shutdown:
break;
}
QTC_ASSERT(false, return false); // should not happen at all
......@@ -285,7 +301,7 @@ bool TestCodeParser::postponed(const QStringList &fileList)
void TestCodeParser::scanForTests(const QStringList &fileList)
{
if (m_parserState == Disabled) {
if (m_parserState == Disabled || m_parserState == Shutdown) {
m_dirty = true;
if (fileList.isEmpty()) {
m_fullUpdatePostponed = true;
......@@ -390,6 +406,9 @@ void TestCodeParser::onFinished()
qCDebug(LOG) << "emitting parsingFinished (onFinished, Disabled)";
emit parsingFinished();
break;
case Shutdown:
qCDebug(LOG) << "Shutdown complete - not emitting parsingFinished (onFinished)";
break;
default:
qWarning("I should not be here... State: %d", m_parserState);
break;
......
......@@ -48,7 +48,8 @@ public:
Idle,
PartialParse,
FullParse,
Disabled
Disabled,
Shutdown
};
explicit TestCodeParser(TestTreeModel *parent = 0);
......@@ -77,6 +78,7 @@ public:
void onQmlDocumentUpdated(const QmlJS::Document::Ptr &document);
void onStartupProjectChanged(ProjectExplorer::Project *project);
void onProjectPartsUpdated(ProjectExplorer::Project *project);
void aboutToShutdown();
private:
bool postponed(const QStringList &fileList);
......
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