summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
authorChristian Strømme <christian.stromme@digia.com>2013-10-11 14:55:33 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-10-17 01:49:19 +0200
commit021c79f038c218a55b145fafcda5c59cf3a309d8 (patch)
tree7fad7d283bafcc49a43c6e6836d5e04b3c9a4314 /src/corelib
parentd0b419e35521d50f1409de84f99ded3b9a7ab01d (diff)
Android: Use java.util.Random in qrand()
Android does not provide rand_r(), so we would fall back to rand() and srand() which means we where not keeping the promise of qrand and qsrand being thread-safe. As a replacement we can use the Java api and have one Random object for each thread. Task-number: QTBUG-32814 Change-Id: Id46d195a0bb122bc7a5a8de43bdf088e11a9c42e Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@digia.com>
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/global/qglobal.cpp36
1 files changed, 36 insertions, 0 deletions
diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp
index ff2c4bbe5e..1dd77c5859 100644
--- a/src/corelib/global/qglobal.cpp
+++ b/src/corelib/global/qglobal.cpp
@@ -76,6 +76,10 @@
#include <CoreServices/CoreServices.h>
#endif
+#if defined(Q_OS_ANDROID)
+#include <private/qjni_p.h>
+#endif
+
QT_BEGIN_NAMESPACE
#if !QT_DEPRECATED_SINCE(5, 0)
@@ -2335,6 +2339,9 @@ typedef uint SeedStorageType;
typedef QThreadStorage<SeedStorageType *> SeedStorage;
Q_GLOBAL_STATIC(SeedStorage, randTLS) // Thread Local Storage for seed value
+#elif defined(Q_OS_ANDROID)
+typedef QThreadStorage<QJNIObjectPrivate> AndroidRandomStorage;
+Q_GLOBAL_STATIC(AndroidRandomStorage, randomTLS)
#endif
/*!
@@ -2368,6 +2375,16 @@ void qsrand(uint seed)
//global static object, fallback to srand(seed)
srand(seed);
}
+#elif defined(Q_OS_ANDROID)
+ QJNIObjectPrivate random = QJNIObjectPrivate("java/util/Random",
+ "(J)V",
+ jlong(seed));
+ if (!random.isValid()) {
+ srand(seed);
+ return;
+ }
+
+ randomTLS->setLocalData(random);
#else
// On Windows srand() and rand() already use Thread-Local-Storage
// to store the seed between calls
@@ -2409,6 +2426,25 @@ int qrand()
//global static object, fallback to rand()
return rand();
}
+#elif defined(Q_OS_ANDROID)
+ AndroidRandomStorage *randomStorage = randomTLS();
+ if (!randomStorage)
+ return rand();
+
+ QJNIObjectPrivate random;
+ if (!randomStorage->hasLocalData()) {
+ random = QJNIObjectPrivate("java/util/Random",
+ "(J)V",
+ jlong(1));
+ if (!random.isValid())
+ return rand();
+
+ randomStorage->setLocalData(random);
+ } else {
+ random = randomStorage->localData();
+ }
+
+ return random.callMethod<jint>("nextInt", "(I)I", RAND_MAX);
#else
// On Windows srand() and rand() already use Thread-Local-Storage
// to store the seed between calls