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>
This commit is contained in:
parent
d0b419e355
commit
021c79f038
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user