From d67ddfb5d1c1d60a2ba06774d90f2ba14432e592 Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Wed, 10 Oct 2018 14:32:00 +0200 Subject: [PATCH] Clang: Avoid starting backend jobs for inactive app and during VCS operations ...to reduce file locking on Windows caused by clangbackend's parse/reparse jobs. Considering inactive application state should help for external VCS operations, e.g. on the command line. However, activating Qt Creator while such a VCS operation runs might still lead to undesired behavior, but this should be the less common case. VCS operations started from within Qt Creator should see less locking conflicts as we know when they start and finish. However, we just avoid starting new jobs - there might be still jobs running. Pending or new jobs will be started once Qt Creator is activated again and all VCS operations finished. Task-number: QTCREATORBUG-15449 Change-Id: I5f04c34f006e66162368efbdd58bd822a706f35e Reviewed-by: Ivan Donchevskii --- .../clangbackendcommunicator.cpp | 28 +++++++++++++++++-- .../clangcodemodel/clangbackendcommunicator.h | 3 ++ .../clangmodelmanagersupport.cpp | 23 ++++++++++++++- .../clangcodemodel/clangmodelmanagersupport.h | 3 ++ src/plugins/cpptools/cppmodelmanager.cpp | 5 ++++ src/plugins/cpptools/cppmodelmanager.h | 2 ++ src/plugins/cpptools/cppmodelmanagersupport.h | 1 + .../cpptools/cppmodelmanagersupportinternal.h | 1 + src/plugins/vcsbase/vcscommand.cpp | 9 ++++-- 9 files changed, 69 insertions(+), 6 deletions(-) diff --git a/src/plugins/clangcodemodel/clangbackendcommunicator.cpp b/src/plugins/clangcodemodel/clangbackendcommunicator.cpp index 6354b505484..4e0c08b6724 100644 --- a/src/plugins/clangcodemodel/clangbackendcommunicator.cpp +++ b/src/plugins/clangcodemodel/clangbackendcommunicator.cpp @@ -207,9 +207,26 @@ bool BackendCommunicator::isNotWaitingForCompletion() const return !m_receiver.isExpectingCompletionsMessage(); } +void BackendCommunicator::setBackendJobsPostponed(bool postponed) +{ + if (postponed) { + if (!m_postponeBackendJobs) + documentVisibilityChanged(Utf8String(), {}); + ++m_postponeBackendJobs; + } else { + if (QTC_GUARD(m_postponeBackendJobs > 0)) + --m_postponeBackendJobs; + if (!m_postponeBackendJobs) + documentVisibilityChanged(); + } +} + void BackendCommunicator::documentVisibilityChanged(const Utf8String ¤tEditorFilePath, const Utf8StringVector &visibleEditorsFilePaths) { + if (m_postponeBackendJobs) + return; + const DocumentVisibilityChangedMessage message(currentEditorFilePath, visibleEditorsFilePaths); m_sender->documentVisibilityChanged(message); } @@ -459,9 +476,14 @@ void BackendCommunicator::initializeBackendWithCurrentData() void BackendCommunicator::documentsOpened(const FileContainers &fileContainers) { - const DocumentsOpenedMessage message(fileContainers, - currentCppEditorDocumentFilePath(), - visibleCppEditorDocumentsFilePaths()); + Utf8String currentDocument; + Utf8StringVector visibleDocuments; + if (!m_postponeBackendJobs) { + currentDocument = currentCppEditorDocumentFilePath(); + visibleDocuments = visibleCppEditorDocumentsFilePaths(); + } + + const DocumentsOpenedMessage message(fileContainers, currentDocument, visibleDocuments); m_sender->documentsOpened(message); } diff --git a/src/plugins/clangcodemodel/clangbackendcommunicator.h b/src/plugins/clangcodemodel/clangbackendcommunicator.h index 7d676cf5a54..9709b60707a 100644 --- a/src/plugins/clangcodemodel/clangbackendcommunicator.h +++ b/src/plugins/clangcodemodel/clangbackendcommunicator.h @@ -108,6 +108,8 @@ public: void updateChangeContentStartPosition(const QString &filePath, int position); bool isNotWaitingForCompletion() const; + void setBackendJobsPostponed(bool postponed); + private: void initializeBackend(); void initializeBackendWithCurrentData(); @@ -134,6 +136,7 @@ private: QTimer m_backendStartTimeOut; QScopedPointer m_sender; int m_connectedCount = 0; + int m_postponeBackendJobs = 1; // Initial application state is inactive, so no jobs should be run. }; } // namespace Internal diff --git a/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp b/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp index de02be4686e..66abc7913b0 100644 --- a/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp +++ b/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp @@ -53,7 +53,7 @@ #include #include -#include +#include #include #include @@ -75,6 +75,8 @@ ModelManagerSupportClang::ModelManagerSupportClang() QTC_CHECK(!m_instance); m_instance = this; + QApplication::instance()->installEventFilter(this); + CppTools::CppModelManager::instance()->setCurrentDocumentFilter( std::make_unique()); @@ -138,6 +140,11 @@ std::unique_ptr ModelManagerSupportClang::creat return std::make_unique(); } +void ModelManagerSupportClang::setBackendJobsPostponed(bool postponed) +{ + m_communicator.setBackendJobsPostponed(postponed); +} + CppTools::BaseEditorDocumentProcessor *ModelManagerSupportClang::createEditorDocumentProcessor( TextEditor::TextDocument *baseTextDocument) { @@ -211,6 +218,20 @@ void ModelManagerSupportClang::connectToWidgetsMarkContextMenuRequested(QWidget } } +bool ModelManagerSupportClang::eventFilter(QObject *obj, QEvent *e) +{ + if (obj == QApplication::instance() && e->type() == QEvent::ApplicationStateChange) { + switch (QApplication::applicationState()) { + case Qt::ApplicationInactive: setBackendJobsPostponed(true); break; + case Qt::ApplicationActive: setBackendJobsPostponed(false); break; + default: + QTC_CHECK(false && "Unexpected Qt::ApplicationState"); + } + } + + return false; +} + void ModelManagerSupportClang::onEditorOpened(Core::IEditor *editor) { QTC_ASSERT(editor, return); diff --git a/src/plugins/clangcodemodel/clangmodelmanagersupport.h b/src/plugins/clangcodemodel/clangmodelmanagersupport.h index e11191006f6..9578804ebb6 100644 --- a/src/plugins/clangcodemodel/clangmodelmanagersupport.h +++ b/src/plugins/clangcodemodel/clangmodelmanagersupport.h @@ -72,6 +72,7 @@ public: CppTools::FollowSymbolInterface &followSymbolInterface() override; CppTools::RefactoringEngineInterface &refactoringEngineInterface() override; std::unique_ptr createOverviewModel() override; + void setBackendJobsPostponed(bool postponed) override; BackendCommunicator &communicator(); QString dummyUiHeaderOnDiskDirPath() const; @@ -82,6 +83,8 @@ public: static ModelManagerSupportClang *instance(); private: + bool eventFilter(QObject *obj, QEvent *e) override; + void onEditorOpened(Core::IEditor *editor); void onEditorClosed(const QList &editors); void onCurrentEditorChanged(Core::IEditor *newCurrent); diff --git a/src/plugins/cpptools/cppmodelmanager.cpp b/src/plugins/cpptools/cppmodelmanager.cpp index 5db9dd601d1..603ff3174b9 100644 --- a/src/plugins/cpptools/cppmodelmanager.cpp +++ b/src/plugins/cpptools/cppmodelmanager.cpp @@ -1326,6 +1326,11 @@ void CppModelManager::renameIncludes(const QString &oldFileName, const QString & } } +void CppModelManager::setBackendJobsPostponed(bool postponed) +{ + d->m_activeModelManagerSupport->setBackendJobsPostponed(postponed); +} + void CppModelManager::onCoreAboutToClose() { Core::ProgressManager::cancelTasks(CppTools::Constants::TASK_INDEX); diff --git a/src/plugins/cpptools/cppmodelmanager.h b/src/plugins/cpptools/cppmodelmanager.h index 66cc1331468..bafc3b32716 100644 --- a/src/plugins/cpptools/cppmodelmanager.h +++ b/src/plugins/cpptools/cppmodelmanager.h @@ -238,6 +238,8 @@ public: void renameIncludes(const QString &oldFileName, const QString &newFileName); + void setBackendJobsPostponed(bool postponed); + signals: /// Project data might be locked while this is emitted. void aboutToRemoveFiles(const QStringList &files); diff --git a/src/plugins/cpptools/cppmodelmanagersupport.h b/src/plugins/cpptools/cppmodelmanagersupport.h index c5457cd51f3..f7ff56ca3bc 100644 --- a/src/plugins/cpptools/cppmodelmanagersupport.h +++ b/src/plugins/cpptools/cppmodelmanagersupport.h @@ -60,6 +60,7 @@ public: virtual FollowSymbolInterface &followSymbolInterface() = 0; virtual RefactoringEngineInterface &refactoringEngineInterface() = 0; virtual std::unique_ptr createOverviewModel() = 0; + virtual void setBackendJobsPostponed(bool yesno) = 0; }; class CPPTOOLS_EXPORT ModelManagerSupportProvider diff --git a/src/plugins/cpptools/cppmodelmanagersupportinternal.h b/src/plugins/cpptools/cppmodelmanagersupportinternal.h index cfa326e7784..b01f38f4b88 100644 --- a/src/plugins/cpptools/cppmodelmanagersupportinternal.h +++ b/src/plugins/cpptools/cppmodelmanagersupportinternal.h @@ -47,6 +47,7 @@ public: FollowSymbolInterface &followSymbolInterface() final; RefactoringEngineInterface &refactoringEngineInterface() final; std::unique_ptr createOverviewModel() final; + void setBackendJobsPostponed(bool) final {} private: QScopedPointer m_completionAssistProvider; diff --git a/src/plugins/vcsbase/vcscommand.cpp b/src/plugins/vcsbase/vcscommand.cpp index af1eac8f32a..4d00e53ee0a 100644 --- a/src/plugins/vcsbase/vcscommand.cpp +++ b/src/plugins/vcsbase/vcscommand.cpp @@ -29,6 +29,7 @@ #include #include +#include #include #include @@ -60,12 +61,16 @@ VcsCommand::VcsCommand(const QString &workingDirectory, return proxy; }); connect(this, &VcsCommand::started, this, [this] { - if (flags() & ExpectRepoChanges) + if (flags() & ExpectRepoChanges) { Core::DocumentManager::setAutoReloadPostponed(true); + CppTools::CppModelManager::instance()->setBackendJobsPostponed(true); + } }); connect(this, &VcsCommand::finished, this, [this] { - if (flags() & ExpectRepoChanges) + if (flags() & ExpectRepoChanges) { Core::DocumentManager::setAutoReloadPostponed(false); + CppTools::CppModelManager::instance()->setBackendJobsPostponed(false); + } }); }