diff options
author | Oswald Buddenhagen <oswald.buddenhagen@qt.io> | 2017-08-14 18:30:29 +0200 |
---|---|---|
committer | Oswald Buddenhagen <oswald.buddenhagen@qt.io> | 2018-03-14 15:34:01 +0000 |
commit | 60245e55d7551f525c951d8d866aab081be88a69 (patch) | |
tree | a835326ccc87ea93d7c749f9f0f42f27d8ab1db2 /src/shared/proparser/qmakevfs.h | |
parent | 274726efb0bbc5055f02b1b76f2481564ad27f46 (diff) | |
download | qt-creator-60245e55d7551f525c951d8d866aab081be88a69.tar.gz |
qmake: Change source identifier type in ProString
The strings remember in which file they were created/assigned.
However, this used a non-counting reference to a ProFile, which could
become dangling. If a subsequent ProFile re-used the exact same address,
a string's source would be mis-identified, which would be fatal in
conjunction with discard_from().
Since we actually need only a unique id for comparison, let's use an
integer for that.
comment on cherry-pick: this is actually a lot more than a cherry-pick,
because the file ids need to be aware of the dual VFS which was
concurrently introduced on the qtc side.
Started-by: Simon Hausmann <simon.hausmann@qt.io>
Change-Id: I395153afaf7c835d0119690ee7f4b915e6f90d4a
(cherry picked from qtbase/190aa94be7f5e146bef44862b974d733755cec85)
Reviewed-by: Tobias Hunger <tobias.hunger@qt.io>
Diffstat (limited to 'src/shared/proparser/qmakevfs.h')
-rw-r--r-- | src/shared/proparser/qmakevfs.h | 55 |
1 files changed, 40 insertions, 15 deletions
diff --git a/src/shared/proparser/qmakevfs.h b/src/shared/proparser/qmakevfs.h index b6b93fb5dd..da0d0626d8 100644 --- a/src/shared/proparser/qmakevfs.h +++ b/src/shared/proparser/qmakevfs.h @@ -27,13 +27,11 @@ #include "qmake_global.h" -# include <qiodevice.h> -#ifndef PROEVALUATOR_FULL -# include <qhash.h> -# include <qstring.h> -# ifdef PROEVALUATOR_THREAD_SAFE -# include <qmutex.h> -# endif +#include <qiodevice.h> +#include <qhash.h> +#include <qstring.h> +#ifdef PROEVALUATOR_THREAD_SAFE +# include <qmutex.h> #endif #ifndef QT_NO_TEXTCODEC @@ -62,23 +60,27 @@ public: VfsExact = 0, #ifdef PROEVALUATOR_DUAL_VFS VfsCumulative = 2, - VfsNoVirtual = 4 + VfsCreate = 4, + VfsCreatedOnly = 8, #else VfsCumulative = 0, - VfsNoVirtual = 0 + VfsCreate = 0, + VfsCreatedOnly = 0, #endif + VfsAccessedOnly = 16 }; Q_DECLARE_FLAGS(VfsFlags, VfsFlag) QMakeVfs(); - bool writeFile(const QString &fn, QIODevice::OpenMode mode, VfsFlags flags, const QString &contents, QString *errStr); - ReadResult readFile(const QString &fn, VfsFlags flags, QString *contents, QString *errStr); - bool exists(const QString &fn, VfsFlags flags); + 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); #ifndef PROEVALUATOR_FULL - bool readVirtualFile(const QString &fn, VfsFlags flags, QString *contents); - void invalidateCache(); void invalidateContents(); #endif @@ -88,11 +90,34 @@ public: #endif private: +#ifdef PROEVALUATOR_THREAD_SAFE + static QMutex s_mutex; +#endif + static QAtomicInt s_fileIdCounter; + // Qt Creator's ProFile cache is a singleton to maximize its cross-project + // effectiveness (shared prf files from QtVersions). + // For this to actually work, real files need a global mapping. + // This is fine, because the namespace of real files is indeed global. + static QHash<QString, int> s_fileIdMap; + static QHash<int, QString> s_idFileMap; +#ifdef PROEVALUATOR_DUAL_VFS +# ifdef PROEVALUATOR_THREAD_SAFE + // The simple way to avoid recursing m_mutex. + QMutex m_vmutex; +# endif + // Virtual files are bound to the project context they were created in, + // so their ids need to be local as well. + // We violate that rule in lupdate (which has a non-dual VFS), but that + // does not matter, because it has only one project context anyway. + QHash<QString, int> m_virtualFileIdMap[2]; // Exact and cumulative + QHash<int, QString> m_virtualIdFileMap; // Only one map, as ids are unique across realms. +#endif + #ifndef PROEVALUATOR_FULL # ifdef PROEVALUATOR_THREAD_SAFE QMutex m_mutex; # endif - QHash<QString, QString> m_files; + QHash<int, QString> m_files; QString m_magicMissing; QString m_magicExisting; #endif |