From d03fb350672d311dccc06f0bcb4da744a3c99745 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 24 May 2018 20:50:32 +0200 Subject: [PATCH] qmake: fix file id mapping lifetime management turns out that flushing the ids together with the ProFile cache was an abysmal idea, as the latter expires after a few seconds after loading the project, while references to the ProFiles (and thus the underlying file ids) are kept for as long as the project stays loaded. the early flush would cause re-use of the file ids, which would wreak all kinds of havoc when re-loading projects. instead, ref-count the vfs class based on its instances. amends 60245e55d7. Task-number: QTCREATORBUG-20113 Change-Id: I7382a71af4d6a991156c05719deae9fb1e4fb278 Reviewed-by: Orgad Shaneh Reviewed-by: Eike Ziller Reviewed-by: Tobias Hunger --- src/plugins/qtsupport/profilereader.cpp | 1 - src/shared/proparser/qmakevfs.cpp | 28 ++++++++++++++++--------- src/shared/proparser/qmakevfs.h | 3 ++- 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/src/plugins/qtsupport/profilereader.cpp b/src/plugins/qtsupport/profilereader.cpp index 86ec0f16d7f..15eb960071c 100644 --- a/src/plugins/qtsupport/profilereader.cpp +++ b/src/plugins/qtsupport/profilereader.cpp @@ -166,7 +166,6 @@ void ProFileCacheManager::clear() // loop is concerned. Use a shared pointer once this is not true anymore. delete m_cache; m_cache = 0; - QMakeVfs::clearIds(); } void ProFileCacheManager::discardFiles(const QString &prefix, QMakeVfs *vfs) diff --git a/src/shared/proparser/qmakevfs.cpp b/src/shared/proparser/qmakevfs.cpp index d7248fbd5be..c5c5b75c749 100644 --- a/src/shared/proparser/qmakevfs.cpp +++ b/src/shared/proparser/qmakevfs.cpp @@ -49,11 +49,29 @@ QMakeVfs::QMakeVfs() #ifndef QT_NO_TEXTCODEC m_textCodec = 0; #endif +#ifdef PROEVALUATOR_THREAD_SAFE + QMutexLocker locker(&s_mutex); +#endif + ++s_refCount; } +QMakeVfs::~QMakeVfs() +{ +#ifdef PROEVALUATOR_THREAD_SAFE + QMutexLocker locker(&s_mutex); +#endif + if (!--s_refCount) { + s_fileIdCounter = 0; + s_fileIdMap.clear(); + s_idFileMap.clear(); + } +} + + #ifdef PROPARSER_THREAD_SAFE QMutex QMakeVfs::s_mutex; #endif +int QMakeVfs::s_refCount; QAtomicInt QMakeVfs::s_fileIdCounter; QHash QMakeVfs::s_fileIdMap; QHash QMakeVfs::s_idFileMap; @@ -111,16 +129,6 @@ QString QMakeVfs::fileNameForId(int id) return s_idFileMap.value(id); } -void QMakeVfs::clearIds() -{ -#ifdef PROEVALUATOR_THREAD_SAFE - QMutexLocker locker(&s_mutex); -#endif - s_fileIdCounter = 0; - s_fileIdMap.clear(); - s_idFileMap.clear(); -} - bool QMakeVfs::writeFile(int id, QIODevice::OpenMode mode, VfsFlags flags, const QString &contents, QString *errStr) { diff --git a/src/shared/proparser/qmakevfs.h b/src/shared/proparser/qmakevfs.h index da0d0626d8f..34dd96fd7b7 100644 --- a/src/shared/proparser/qmakevfs.h +++ b/src/shared/proparser/qmakevfs.h @@ -72,10 +72,10 @@ public: Q_DECLARE_FLAGS(VfsFlags, VfsFlag) QMakeVfs(); + ~QMakeVfs(); int idForFileName(const QString &fn, VfsFlags flags); QString fileNameForId(int id); - static void clearIds(); bool writeFile(int id, QIODevice::OpenMode mode, VfsFlags flags, const QString &contents, QString *errStr); ReadResult readFile(int id, QString *contents, QString *errStr); bool exists(const QString &fn, QMakeVfs::VfsFlags flags); @@ -93,6 +93,7 @@ private: #ifdef PROEVALUATOR_THREAD_SAFE static QMutex s_mutex; #endif + static int s_refCount; static QAtomicInt s_fileIdCounter; // Qt Creator's ProFile cache is a singleton to maximize its cross-project // effectiveness (shared prf files from QtVersions).