From f12fd482f50fde77f11d3c45309d538c02b9d334 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 24 May 2018 20:50:32 +0200 Subject: 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. but just ref-counting the vfs class is insufficient as well, as then the ProFile cache (which expires after a timeout) could outlive all VFS instances and thus refer to ids which were discarded and later re-used. so we ref-count, and additionally let the cache instance hold a reference to the vfs class. this is sync-up with qt creator; no actual effect on qmake itself. amends 190aa94be. Change-Id: Idd4478ffc1c2405b3b83df32fba45b1f687f6a18 Reviewed-by: Robert Loehning Reviewed-by: Orgad Shaneh Reviewed-by: Eike Ziller Reviewed-by: Tobias Hunger (cherry picked from qtcreator/d03fb350672d311dccc06f0bcb4da744a3c99745) (cherry picked from qtcreator/1ddfb443b686ef04cc0e28363308ce70d01f0d73) Reviewed-by: Oswald Buddenhagen --- qmake/library/qmakeparser.cpp | 6 ++++++ qmake/library/qmakeparser.h | 2 +- qmake/library/qmakevfs.cpp | 37 +++++++++++++++++++++++++++---------- qmake/library/qmakevfs.h | 6 +++++- 4 files changed, 39 insertions(+), 12 deletions(-) (limited to 'qmake') diff --git a/qmake/library/qmakeparser.cpp b/qmake/library/qmakeparser.cpp index 131ec6db6a..4c8360b459 100644 --- a/qmake/library/qmakeparser.cpp +++ b/qmake/library/qmakeparser.cpp @@ -45,11 +45,17 @@ QT_BEGIN_NAMESPACE // /////////////////////////////////////////////////////////////////////// +ProFileCache::ProFileCache() +{ + QMakeVfs::ref(); +} + ProFileCache::~ProFileCache() { for (const Entry &ent : qAsConst(parsed_files)) if (ent.pro) ent.pro->deref(); + QMakeVfs::deref(); } void ProFileCache::discardFile(const QString &fileName, QMakeVfs *vfs) diff --git a/qmake/library/qmakeparser.h b/qmake/library/qmakeparser.h index e9529f8bf6..7b96d4e88f 100644 --- a/qmake/library/qmakeparser.h +++ b/qmake/library/qmakeparser.h @@ -201,7 +201,7 @@ Q_DECLARE_OPERATORS_FOR_FLAGS(QMakeParser::ParseFlags) class QMAKE_EXPORT ProFileCache { public: - ProFileCache() {} + ProFileCache(); ~ProFileCache(); void discardFile(int id); diff --git a/qmake/library/qmakevfs.cpp b/qmake/library/qmakevfs.cpp index 2239a2beec..3a54ef4023 100644 --- a/qmake/library/qmakevfs.cpp +++ b/qmake/library/qmakevfs.cpp @@ -52,11 +52,38 @@ QMakeVfs::QMakeVfs() #ifndef QT_NO_TEXTCODEC m_textCodec = 0; #endif + ref(); +} + +QMakeVfs::~QMakeVfs() +{ + deref(); +} + +void QMakeVfs::ref() +{ +#ifdef PROEVALUATOR_THREAD_SAFE + QMutexLocker locker(&s_mutex); +#endif + ++s_refCount; +} + +void QMakeVfs::deref() +{ +#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; @@ -114,16 +141,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/qmake/library/qmakevfs.h b/qmake/library/qmakevfs.h index 1217225471..68c21a3d37 100644 --- a/qmake/library/qmakevfs.h +++ b/qmake/library/qmakevfs.h @@ -76,10 +76,13 @@ public: Q_DECLARE_FLAGS(VfsFlags, VfsFlag) QMakeVfs(); + ~QMakeVfs(); + + static void ref(); + static void deref(); 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); @@ -97,6 +100,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). -- cgit v1.2.3