summaryrefslogtreecommitdiffstats
path: root/src/corelib/tools
diff options
context:
space:
mode:
authorSamuel Nevala <samuel.nevala@intopalo.com>2015-11-19 13:12:41 +0200
committerSamuel Nevala <samuel.nevala@intopalo.com>2015-11-23 19:58:16 +0000
commit5b62a5e7aabcc818408f2fe28b9760082f474def (patch)
tree2e048078e999b9884642b8395da54ecb555851ae /src/corelib/tools
parentfa00afe7d760d91cf9c91f57dd2f77625e758e28 (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')
-rw-r--r--src/corelib/tools/qhash.cpp15
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
*/