From 77270648e8687c00329dc0cba62d4befcb228d8c Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Tue, 13 Oct 2015 16:54:59 +0200 Subject: [PATCH] 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 --- src/plugins/cpptools/cppmodelmanager.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/plugins/cpptools/cppmodelmanager.cpp b/src/plugins/cpptools/cppmodelmanager.cpp index 0b8ccc8fe6a..70012ab682c 100644 --- a/src/plugins/cpptools/cppmodelmanager.cpp +++ b/src/plugins/cpptools/cppmodelmanager.cpp @@ -831,6 +831,7 @@ QFuture CppModelManager::updateProjectInfo(const ProjectInfo &newProjectIn return QFuture(); QSet 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 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 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());