diff -r 5dc02b23752f -r 3e2da88830cd src/corelib/plugin/quuid.cpp --- a/src/corelib/plugin/quuid.cpp Tue Jul 06 15:10:48 2010 +0300 +++ b/src/corelib/plugin/quuid.cpp Wed Aug 18 10:37:55 2010 +0300 @@ -546,13 +546,13 @@ \fn QUuid QUuid::createUuid() On any platform other than Windows, this function returns a new - UUID with variant QUuid::DCE and version QUuid::Random. The random - numbers used to construct the UUID are obtained from the local - pseudo-random generator, qrand(), which is usually not a cryptographic - quality random number generator. Therefore, a UUID generated by - this function can't be guaranteed to be unique. If the pseudo-random - number generator for the calling thread has not yet been seeded, this - function will seed the pseudo-random number generator by calling qsrand(). + UUID with variant QUuid::DCE and version QUuid::Random. If + the /dev/urandom device exists, then the numbers used to construct + the UUID will be of cryptographic quality, which will make the UUID + unique. Otherwise, the numbers of the UUID will be obtained from + the local pseudo-random number generator (qrand(), which is seeded + by qsrand()) which is usually not of cryptograhic quality, which + means that the UUID can't be guaranteed to be unique. On a Windows platform, a GUID is generated, which almost certainly \e{will} be unique, on this or any other system, networked or not. @@ -577,31 +577,62 @@ QT_BEGIN_INCLUDE_NAMESPACE #include "qdatetime.h" -#include "stdlib.h" // For srand/rand +#include "qfile.h" +#include "qthreadstorage.h" +#include // for RAND_MAX QT_END_INCLUDE_NAMESPACE -extern void qsrand(); // in qglobal.cpp - QUuid QUuid::createUuid() { - static const int intbits = sizeof(int)*8; - static int randbits = 0; - if (!randbits) { - int max = RAND_MAX; - do { ++randbits; } while ((max=max>>1)); - } - - // reseed, but only if not already seeded - qsrand(); - QUuid result; uint *data = &(result.data1); - int chunks = 16 / sizeof(uint); - while (chunks--) { - uint randNumber = 0; - for (int filled = 0; filled < intbits; filled += randbits) - randNumber |= qrand()<>1)); + randbits = r; + } + + // 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). +#ifndef QT_BOOTSTRAPPED + static QThreadStorage uuidseed; + if (!uuidseed.hasLocalData()) + { + 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); + } +#else + static bool seeded = false; + if (!seeded) + qsrand(QDateTime::currentDateTime().toTime_t() + + quintptr(&seeded)); +#endif + + int chunks = 16 / sizeof(uint); + while (chunks--) { + uint randNumber = 0; + for (int filled = 0; filled < intbits; filled += randbits) + randNumber |= qrand()<