diff options
author | Samuel Nevala <samuel.nevala@intopalo.com> | 2015-11-19 13:12:41 +0200 |
---|---|---|
committer | Samuel Nevala <samuel.nevala@intopalo.com> | 2015-11-23 19:58:16 +0000 |
commit | 5b62a5e7aabcc818408f2fe28b9760082f474def (patch) | |
tree | 2e048078e999b9884642b8395da54ecb555851ae /src/corelib/tools/qhash.cpp | |
parent | fa00afe7d760d91cf9c91f57dd2f77625e758e28 (diff) |
Fix deadlock when setting environment variables.
Qt uses QHash as the container for faking environment variables on
Windows Runtime and CE. Environment variable manipulation functions are
protected by mutex. Accessing the QT_HASH_SEED environment variable
inside QHash can lead to situation where qputenv() call leads to
qgetenv() call and that leads to a deadlock. Since the application
environment is faked anyway, drop support for QT_HASH_SEED and ifdef
that functionality out on those platforms. Documentation is updated
to reflect changes.
Task-number: QTBUG-49529
Change-Id: I1b1c28cb0b041fe2a63ca3dce57068fcb46505a7
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com>
Reviewed-by: Andrew Knight <andrew.knight@intopalo.com>
Diffstat (limited to 'src/corelib/tools/qhash.cpp')
-rw-r--r-- | src/corelib/tools/qhash.cpp | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/src/corelib/tools/qhash.cpp b/src/corelib/tools/qhash.cpp index b334a697a9..fe49e8c6a8 100644 --- a/src/corelib/tools/qhash.cpp +++ b/src/corelib/tools/qhash.cpp @@ -38,6 +38,14 @@ #ifndef _CRT_RAND_S #define _CRT_RAND_S #endif + +// Windows Runtime and CE use a QHash to fake environment variables. To avoid +// deadlock, disable reading the QT_HASH_SEED environment variable within +// QHash. +#if defined(Q_OS_WINRT) || defined(Q_OS_WINCE) +# define QHASH_NO_ENV_SEED +#endif + #include <stdlib.h> #include "qhash.h" @@ -223,9 +231,11 @@ static uint qt_create_qhash_seed() uint seed = 0; #ifndef QT_BOOTSTRAPPED +#ifdef QHASH_NO_ENV_SEED QByteArray envSeed = qgetenv("QT_HASH_SEED"); if (!envSeed.isNull()) return envSeed.toUInt(); +#endif // QHASH_NO_ENV_SEED #ifdef Q_OS_UNIX int randomfd = qt_safe_open("/dev/urandom", O_RDONLY); @@ -327,8 +337,10 @@ int qGlobalQHashSeed() */ void qSetGlobalQHashSeed(int newSeed) { +#ifdef QHASH_NO_ENV_SEED if (qEnvironmentVariableIsSet("QT_HASH_SEED")) return; +#endif // QHASH_NO_ENV_SEED if (newSeed == -1) { int x(qt_create_qhash_seed() & INT_MAX); qt_qhash_seed.store(x); @@ -1182,6 +1194,9 @@ uint qHash(long double key, uint seed) Q_DECL_NOTHROW decimal value, will be used as the seed for qHash(). Alternatively, you can call the qSetGlobalQHashSeed() function. + \note The environment variable \c QT_HASH_SEED is unsupported on Windows + Runtime and CE. Use qSetGlobalQHashSeed() instead on those platforms. + \sa QHashIterator, QMutableHashIterator, QMap, QSet */ |