Commit 7583039b authored by Nikolai Kosjar's avatar Nikolai Kosjar

CppTools: Do not call GC() more than necessary

Currently GC() is invoked if
   - 5 CppEditors were closed or the last CppEditor was closed
   - a project is about to be removed
   - a session is about to be unloaded

Thus, for the following use cases, too much GC() calls (can) happen:
    - File > Close All
    - Close All Projects and Editors
    - Changing the session

Fixed by introducing a timer.

Change-Id: I9c984d9de735fc8c6ee77a518e9fb5b63dba5881
Reviewed-by: default avatarErik Verbruggen <erik.verbruggen@digia.com>
parent 4bc61eca
......@@ -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)
......
......@@ -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
......
......@@ -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));
......
......@@ -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;
}
......@@ -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;
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment