diff options
author | Bradley T. Hughes <bradley.hughes@nokia.com> | 2010-07-12 12:18:29 (GMT) |
---|---|---|
committer | Bradley T. Hughes <bradley.hughes@nokia.com> | 2010-07-13 08:28:36 (GMT) |
commit | a0fffeed6fceb8244328b649a3f6feb520493bc2 (patch) | |
tree | e6f70e8852c0687cc2a58ba65b9d67a08e011d43 | |
parent | 4ba6646150300feb79af9510c7c5d238d653a98e (diff) | |
download | Qt-a0fffeed6fceb8244328b649a3f6feb520493bc2.zip Qt-a0fffeed6fceb8244328b649a3f6feb520493bc2.tar.gz Qt-a0fffeed6fceb8244328b649a3f6feb520493bc2.tar.bz2 |
Fix regression in tst_qrand::testqrand()
qrand() has seeded with a default value of 1 for quite a long time, and
is checked by the test mentioned above. The previous commit to change
the default seed value must be reverted to keep compatibility.
Change qrand() and qsrand() back to the way they were in 4.5. This fixes
the qrand() regression.
Change QUuid::createUuid() to seed exactly once per thread, which is a
change from 4.5, where QUuid would see only once per application. This
solves the original bug, QTBUG-3543, where multiple threads would
generate the same UUID sequences. This also fixes the regression
reported in QTBUG-11213, where seeding did not happen in certain cases.
Reviewed-by: Prasanth Ullattil
-rw-r--r-- | src/corelib/global/qglobal.cpp | 9 | ||||
-rw-r--r-- | src/corelib/plugin/quuid.cpp | 14 |
2 files changed, 15 insertions, 8 deletions
diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index b24ba38..12745e9 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -2609,14 +2609,7 @@ int qrand() SeedStorageType *pseed = seedStorage->localData(); if (!pseed) { seedStorage->setLocalData(pseed = new SeedStorageType); - - // Seed the PRNG, but only if it has not already been seeded. The - // default seed is a combination of current time, a stack address - // and a serial counter (since thread stack addresses are re-used). - static QBasicAtomicInt serial = Q_BASIC_ATOMIC_INITIALIZER(2); - *pseed = QDateTime::currentDateTime().toTime_t() - + quintptr(&pseed) - + serial.fetchAndAddRelaxed(1); + *pseed = 1; } return rand_r(pseed); } else { diff --git a/src/corelib/plugin/quuid.cpp b/src/corelib/plugin/quuid.cpp index f48cc2e..d0c59a4 100644 --- a/src/corelib/plugin/quuid.cpp +++ b/src/corelib/plugin/quuid.cpp @@ -577,6 +577,7 @@ QUuid QUuid::createUuid() QT_BEGIN_INCLUDE_NAMESPACE #include "qdatetime.h" +#include "qthreadstorage.h" #include <stdlib.h> // for RAND_MAX QT_END_INCLUDE_NAMESPACE @@ -591,6 +592,19 @@ QUuid QUuid::createUuid() randbits = r; } + static QThreadStorage<int *> uuidseed; + if (!uuidseed.hasLocalData()) { + // Seed the PRNG once per thread with a combination of current time, a + // stack address and a serial counter (since thread stack addresses are + // re-used). + int *pseed = new int; + static QBasicAtomicInt serial = Q_BASIC_ATOMIC_INITIALIZER(2); + qsrand(*pseed = QDateTime::currentDateTime().toTime_t() + + quintptr(&pseed) + + serial.fetchAndAddRelaxed(1)); + uuidseed.setLocalData(pseed); + } + QUuid result; uint *data = &(result.data1); int chunks = 16 / sizeof(uint); |