CppTools: Fix dead lock on project unloading

...with the clang code model.

In updateProjectInfo() we lock the project mutex and emit a signal.
However, the correspondig slot in the clang code model will call back
into a function that needs to lock the mutex, too:

    CppTools::CppModelManager::workingCopy // dead locks here
    CppTools::BaseEditorDocumentParser::InMemoryInfo::InMemoryInfo
    ClangCodeModel::Internal::ClangEditorDocumentProcessor::run
    ClangCodeModel::Internal::ModelManagerSupportClang::unregisterTranslationUnitsWithProjectParts
    ClangCodeModel::Internal::ModelManagerSupportClang::onProjectPartsRemoved
     ...
    CppTools::CppModelManager::projectPartsRemoved
    CppTools::CppModelManager::updateProjectInfo // emits here

Fixed by emitting the signal after releasing the mutex.

Change-Id: Id3f3cd22b0604f343ada56ea13c26f0dc1a75bd6
Reviewed-by: Marco Bubke <marco.bubke@theqtcompany.com>
This commit is contained in:
Nikolai Kosjar
2015-10-13 16:54:59 +02:00
parent 924c8bf8b1
commit 77270648e8

View File

@@ -831,6 +831,7 @@ QFuture<void> CppModelManager::updateProjectInfo(const ProjectInfo &newProjectIn
return QFuture<void>();
QSet<QString> filesToReindex;
QStringList removedProjectParts;
bool filesRemoved = false;
{ // Only hold the mutex for a limited scope, so the dumping afterwards does not deadlock.
@@ -876,8 +877,7 @@ QFuture<void> CppModelManager::updateProjectInfo(const ProjectInfo &newProjectIn
}
}
// Announce removed project parts
emit projectPartsRemoved(comparer.removedProjectParts());
removedProjectParts = comparer.removedProjectParts();
// A new project was opened/created, do a full indexing
} else {
@@ -899,6 +899,10 @@ QFuture<void> CppModelManager::updateProjectInfo(const ProjectInfo &newProjectIn
if (filesRemoved)
GC();
// Announce removed project parts
if (!removedProjectParts.isEmpty())
emit projectPartsRemoved(removedProjectParts);
// Announce added project parts
emit projectPartsUpdated(newProjectInfo.project().data());