ClassView: Fix a possible crash on session switch

Don't call SessionManager methods in non-main thread.
It's not safe to call SessionManger::projects() or
any method of Project class in a non-main thread,
as in meantime the Project object may get deleted
or the Project object may change in main thread in
a not thread-safe way.

Instead, prepare the data needed for the parser's
thread before, when scheduling a call in a main thread,
and pass this data in a safe way.

This fixes possible crash in class view, e.g. on session
switch.

Task-number: QTCREATORBUG-25317
Fixes: QTCREATORBUG-25312
Change-Id: I114aae788aec649d1de3b3d3afdd049ed1e9b2c6
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
This commit is contained in:
Jarek Kobus
2021-03-01 15:01:35 +01:00
parent ced7a2e51f
commit 8fad758f60
4 changed files with 124 additions and 150 deletions

View File

@@ -54,28 +54,29 @@ public:
void requestCurrentState();
void removeFiles(const QStringList &fileList);
void resetDataToCurrentState();
void resetData(const QHash<Utils::FilePath, QPair<QString, Utils::FilePaths>> &projects);
void addProject(const Utils::FilePath &projectPath, const QString &projectName,
const Utils::FilePaths &filesInProject);
void removeProject(const Utils::FilePath &projectPath);
void setFlatMode(bool flat);
void updateDocuments(const QList<CPlusPlus::Document::Ptr> &docs);
void updateDocuments(const QSet<Utils::FilePath> &documentPaths);
signals:
void treeRegenerated(const ParserTreeItem::ConstPtr &root);
private:
void setFileList(const QStringList &fileList);
void resetData(const CPlusPlus::Snapshot &snapshot);
void updateDocumentsFromSnapshot(const QSet<Utils::FilePath> &documentPaths,
const CPlusPlus::Snapshot &snapshot);
ParserTreeItem::ConstPtr getParseDocumentTree(const CPlusPlus::Document::Ptr &doc);
ParserTreeItem::ConstPtr getCachedOrParseDocumentTree(const CPlusPlus::Document::Ptr &doc);
ParserTreeItem::ConstPtr getParseProjectTree(const QStringList &fileList, const QString &projectId);
ParserTreeItem::ConstPtr getCachedOrParseProjectTree(const QStringList &fileList,
const QString &projectId);
ParserTreeItem::ConstPtr getParseProjectTree(const Utils::FilePath &projectPath,
const QSet<Utils::FilePath> &filesInProject);
ParserTreeItem::ConstPtr getCachedOrParseProjectTree(const Utils::FilePath &projectPath,
const QSet<Utils::FilePath> &filesInProject);
ParserTreeItem::ConstPtr parse();
QStringList getAllFiles(const ProjectExplorer::Project *project);
ParserTreeItem::ConstPtr addFlatTree(const ProjectExplorer::Project *project);
//! Private class data pointer
ParserPrivate *d;
};