CMake: Break loop in error handling

Block access to the BuildDirManager while one of its errors is
processed. This prevents more errors being raised as part of
error handling, which can trigger a loop.

Task-number: QTCREATORBUG-17869
Change-Id: Ic6f8d9a3c3b4e63f27260c40f27ab09d20b62b3e
Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
This commit is contained in:
Tobias Hunger
2017-03-24 19:35:13 +01:00
parent 17b89cd422
commit 3a20cec60a
2 changed files with 26 additions and 2 deletions

View File

@@ -75,7 +75,7 @@ const Utils::FileName BuildDirManager::workDirectory() const
if (!m_tempDir) {
m_tempDir.reset(new Utils::TemporaryDirectory("qtc-cmake-XXXXXXXX"));
if (!m_tempDir->isValid())
emit errorOccured(tr("Failed to create temporary directory \"%1\".").arg(m_tempDir->path()));
emitErrorOccured(tr("Failed to create temporary directory \"%1\".").arg(m_tempDir->path()));
}
return Utils::FileName::fromString(m_tempDir->path());
}
@@ -86,6 +86,13 @@ void BuildDirManager::emitDataAvailable()
emit dataAvailable();
}
void BuildDirManager::emitErrorOccured(const QString &message) const
{
m_isHandlingError = true;
emit errorOccured(message);
m_isHandlingError = false;
}
void BuildDirManager::updateReaderType(std::function<void()> todo)
{
BuildDirReader::Parameters p(m_buildConfiguration);
@@ -98,7 +105,7 @@ void BuildDirManager::updateReaderType(std::function<void()> todo)
connect(m_reader.get(), &BuildDirReader::dataAvailable,
this, &BuildDirManager::emitDataAvailable);
connect(m_reader.get(), &BuildDirReader::errorOccured,
this, &BuildDirManager::errorOccured);
this, &BuildDirManager::emitErrorOccured);
connect(m_reader.get(), &BuildDirReader::dirty, this, &BuildDirManager::becameDirty);
}
m_reader->setParameters(p);
@@ -216,6 +223,8 @@ void BuildDirManager::becameDirty()
void BuildDirManager::forceReparse()
{
QTC_ASSERT(!m_isHandlingError, return);
if (m_buildConfiguration->target()->activeBuildConfiguration() != m_buildConfiguration)
return;
@@ -228,6 +237,8 @@ void BuildDirManager::forceReparse()
void BuildDirManager::resetData()
{
QTC_ASSERT(!m_isHandlingError, return);
if (m_reader)
m_reader->resetData();
@@ -259,6 +270,7 @@ bool BuildDirManager::persistCMakeState()
void BuildDirManager::generateProjectTree(CMakeProjectNode *root, const QList<const FileNode *> &allFiles)
{
QTC_ASSERT(!m_isHandlingError, return);
QTC_ASSERT(m_reader, return);
const Utils::FileName projectFile = m_buildConfiguration->target()->project()->projectFilePath();
@@ -272,6 +284,7 @@ void BuildDirManager::generateProjectTree(CMakeProjectNode *root, const QList<co
void BuildDirManager::updateCodeModel(CppTools::RawProjectParts &rpps)
{
QTC_ASSERT(!m_isHandlingError, return);
QTC_ASSERT(m_reader, return);
return m_reader->updateCodeModel(rpps);
}
@@ -283,6 +296,8 @@ void BuildDirManager::parse()
void BuildDirManager::clearCache()
{
QTC_ASSERT(!m_isHandlingError, return);
auto cmakeCache = Utils::FileName(workDirectory()).appendPath(QLatin1String("CMakeCache.txt"));
auto cmakeFiles = Utils::FileName(workDirectory()).appendPath(QLatin1String("CMakeFiles"));
@@ -298,6 +313,8 @@ void BuildDirManager::clearCache()
QList<CMakeBuildTarget> BuildDirManager::buildTargets() const
{
QTC_ASSERT(!m_isHandlingError, return {});
if (!m_reader)
return QList<CMakeBuildTarget>();
if (m_buildTargets.isEmpty())
@@ -307,6 +324,8 @@ QList<CMakeBuildTarget> BuildDirManager::buildTargets() const
CMakeConfig BuildDirManager::parsedConfiguration() const
{
QTC_ASSERT(!m_isHandlingError, return {});
if (!m_reader)
return m_cmakeCache;
if (m_cmakeCache.isEmpty())
@@ -389,6 +408,9 @@ void BuildDirManager::checkConfiguration()
void BuildDirManager::maybeForceReparse()
{
if (m_isHandlingError)
return;
if (!m_reader || !m_reader->hasData()) {
forceReparse();
return;