diff --git a/src/plugins/cpptools/cppmodelmanager.cpp b/src/plugins/cpptools/cppmodelmanager.cpp index ed1ebd14794b02ee40865be2c89fdba031b516f6..cc1979d6b70733a5f81b3cf3b5b9245ca3ea80c4 100644 --- a/src/plugins/cpptools/cppmodelmanager.cpp +++ b/src/plugins/cpptools/cppmodelmanager.cpp @@ -233,6 +233,10 @@ CppModelManager::CppModelManager(QObject *parent) ProjectExplorer::ProjectExplorerPlugin *pe = ProjectExplorer::ProjectExplorerPlugin::instance(); QTC_ASSERT(pe, return); + m_delayedGcTimer = new QTimer(this); + m_delayedGcTimer->setSingleShot(true); + connect(m_delayedGcTimer, SIGNAL(timeout()), this, SLOT(GC())); + ProjectExplorer::SessionManager *session = pe->session(); connect(session, SIGNAL(projectAdded(ProjectExplorer::Project*)), this, SLOT(onProjectAdded(ProjectExplorer::Project*))); @@ -240,6 +244,9 @@ CppModelManager::CppModelManager(QObject *parent) connect(session, SIGNAL(aboutToRemoveProject(ProjectExplorer::Project*)), this, SLOT(onAboutToRemoveProject(ProjectExplorer::Project*))); + connect(session, SIGNAL(aboutToLoadSession(QString)), + this, SLOT(onAboutToLoadSession())); + connect(session, SIGNAL(aboutToUnloadSession(QString)), this, SLOT(onAboutToUnloadSession())); @@ -481,7 +488,7 @@ void CppModelManager::deleteCppEditorSupport(TextEditor::BaseTextEditor *textEdi ++numberOfClosedEditors; if (numberOfOpenEditors == 0 || numberOfClosedEditors == 5) { numberOfClosedEditors = 0; - GC(); + delayedGC(); } } @@ -663,6 +670,11 @@ void CppModelManager::onProjectAdded(ProjectExplorer::Project *) m_dirty = true; } +void CppModelManager::delayedGC() +{ + m_delayedGcTimer->start(500); +} + void CppModelManager::onAboutToRemoveProject(ProjectExplorer::Project *project) { do { @@ -671,6 +683,13 @@ void CppModelManager::onAboutToRemoveProject(ProjectExplorer::Project *project) m_projectToProjectsInfo.remove(project); } while (0); + delayedGC(); +} + +void CppModelManager::onAboutToLoadSession() +{ + if (m_delayedGcTimer->isActive()) + m_delayedGcTimer->stop(); GC(); } @@ -683,8 +702,6 @@ void CppModelManager::onAboutToUnloadSession() m_projectToProjectsInfo.clear(); m_dirty = true; } while (0); - - GC(); } void CppModelManager::onCoreAboutToClose() @@ -729,6 +746,7 @@ void CppModelManager::GC() // Announce removing files and replace the snapshot emit aboutToRemoveFiles(notReachableFiles); replaceSnapshot(newSnapshot); + emit gcFinished(); } void CppModelManager::finishedRefreshingSourceFiles(const QStringList &files) diff --git a/src/plugins/cpptools/cppmodelmanager.h b/src/plugins/cpptools/cppmodelmanager.h index 7024ae1780dedf78ebd0648d8b612f14389cb1dd..a8ca3ee1a0319aeed2b62d2e08f1e386c3c1b12a 100644 --- a/src/plugins/cpptools/cppmodelmanager.h +++ b/src/plugins/cpptools/cppmodelmanager.h @@ -39,6 +39,7 @@ #include <QHash> #include <QMutex> +#include <QTimer> namespace Core { class IEditor; } namespace TextEditor { class BaseTextEditorWidget; } @@ -77,7 +78,6 @@ public: virtual CPlusPlus::Snapshot snapshot() const; virtual Document::Ptr document(const QString &fileName) const; bool replaceDocument(Document::Ptr newDoc); - virtual void GC(); void emitDocumentUpdated(CPlusPlus::Document::Ptr doc); @@ -143,18 +143,22 @@ public: signals: void aboutToRemoveFiles(const QStringList &files); + void gcFinished(); // Needed for tests. public slots: virtual void updateModifiedSourceFiles(); + virtual void GC(); private slots: // This should be executed in the GUI thread. void onAboutToRemoveProject(ProjectExplorer::Project *project); + void onAboutToLoadSession(); void onAboutToUnloadSession(); void onCoreAboutToClose(); void onProjectAdded(ProjectExplorer::Project *project); private: + void delayedGC(); void replaceSnapshot(const CPlusPlus::Snapshot &newSnapshot); WorkingCopy buildWorkingCopyList(); @@ -207,6 +211,7 @@ private: CppFindReferences *m_findReferences; bool m_enableGC; + QTimer *m_delayedGcTimer; }; } // namespace Internal diff --git a/src/plugins/cpptools/cppmodelmanager_test.cpp b/src/plugins/cpptools/cppmodelmanager_test.cpp index 669c086d529eff6e1778b1b85e9854b41beafa93..7e649a9c014bbcafce97f2d19011311e6d41d3db 100644 --- a/src/plugins/cpptools/cppmodelmanager_test.cpp +++ b/src/plugins/cpptools/cppmodelmanager_test.cpp @@ -472,6 +472,8 @@ void CppToolsPlugin::test_modelmanager_snapshot_after_two_projects() /// though it might not be actually generated in the build dir. void CppToolsPlugin::test_modelmanager_extraeditorsupport_uiFiles() { + ModelManagerTestHelper helper; + TestDataDirectory testDataDirectory(QLatin1String("testdata_guiproject1")); const QString projectFile = testDataDirectory.file(QLatin1String("testdata_guiproject1.pro")); @@ -515,13 +517,15 @@ void CppToolsPlugin::test_modelmanager_extraeditorsupport_uiFiles() // Close Project ProjectExplorer::SessionManager *sm = pe->session(); sm->removeProject(project); - ModelManagerTestHelper::verifyClean(); + helper.waitForFinishedGc(); } /// QTCREATORBUG-9828: Locator shows symbols of closed files /// Check: The garbage collector should be run if the last CppEditor is closed. void CppToolsPlugin::test_modelmanager_gc_if_last_cppeditor_closed() { + ModelManagerTestHelper helper; + TestDataDirectory testDataDirectory(QLatin1String("testdata_guiproject1")); const QString file = testDataDirectory.file(QLatin1String("main.cpp")); @@ -541,6 +545,7 @@ void CppToolsPlugin::test_modelmanager_gc_if_last_cppeditor_closed() // Close file/editor em->closeEditor(editor, /*askAboutModifiedEditors=*/ false); + helper.waitForFinishedGc(); // Check: File is removed from the snapshpt QVERIFY(!mm->workingCopy().contains(file)); diff --git a/src/plugins/cpptools/modelmanagertesthelper.cpp b/src/plugins/cpptools/modelmanagertesthelper.cpp index 46f2a91723968338d2db34026e6cac72fc31250e..4d7590e130d079a7ff87c1c4f989b788227eedc6 100644 --- a/src/plugins/cpptools/modelmanagertesthelper.cpp +++ b/src/plugins/cpptools/modelmanagertesthelper.cpp @@ -55,6 +55,7 @@ ModelManagerTestHelper::ModelManagerTestHelper(QObject *parent) : connect(this, SIGNAL(aboutToRemoveProject(ProjectExplorer::Project*)), mm, SLOT(onAboutToRemoveProject(ProjectExplorer::Project*))); connect(this, SIGNAL(projectAdded(ProjectExplorer::Project*)), mm, SLOT(onProjectAdded(ProjectExplorer::Project*))); connect(mm, SIGNAL(sourceFilesRefreshed(QStringList)), this, SLOT(sourceFilesRefreshed(QStringList))); + connect(mm, SIGNAL(gcFinished()), this, SLOT(gcFinished())); cleanup(); verifyClean(); @@ -74,6 +75,9 @@ void ModelManagerTestHelper::cleanup() QList<ProjectInfo> pies = mm->projectInfos(); foreach (const ProjectInfo &pie, pies) emit aboutToRemoveProject(pie.project().data()); + + if (!pies.isEmpty()) + waitForFinishedGc(); } void ModelManagerTestHelper::verifyClean() @@ -108,9 +112,21 @@ QStringList ModelManagerTestHelper::waitForRefreshedSourceFiles() return m_lastRefreshedSourceFiles; } +void ModelManagerTestHelper::waitForFinishedGc() +{ + m_gcFinished = false; + + while (!m_gcFinished) + QCoreApplication::processEvents(); +} void ModelManagerTestHelper::sourceFilesRefreshed(const QStringList &files) { m_lastRefreshedSourceFiles = files; m_refreshHappened = true; } + +void ModelManagerTestHelper::gcFinished() +{ + m_gcFinished = true; +} diff --git a/src/plugins/cpptools/modelmanagertesthelper.h b/src/plugins/cpptools/modelmanagertesthelper.h index b2b042c445212fb09a0f80cc6d6670e1a1b61fe6..d4ac671bc1b4856624d4a9920f126ee19b401721 100644 --- a/src/plugins/cpptools/modelmanagertesthelper.h +++ b/src/plugins/cpptools/modelmanagertesthelper.h @@ -84,6 +84,7 @@ public: Project *createProject(const QString &name); QStringList waitForRefreshedSourceFiles(); + void waitForFinishedGc(); signals: void aboutToRemoveProject(ProjectExplorer::Project *project); @@ -91,8 +92,10 @@ signals: public slots: void sourceFilesRefreshed(const QStringList &files); + void gcFinished(); private: + bool m_gcFinished; bool m_refreshHappened; QStringList m_lastRefreshedSourceFiles; };