summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/llcommon/lluuid.cpp37
-rw-r--r--indra/llcommon/lluuid.h3
-rw-r--r--indra/test/lluuidhashmap_tut.cpp9
3 files changed, 36 insertions, 13 deletions
diff --git a/indra/llcommon/lluuid.cpp b/indra/llcommon/lluuid.cpp
index db8c9c85ab..0aaa50d231 100644
--- a/indra/llcommon/lluuid.cpp
+++ b/indra/llcommon/lluuid.cpp
@@ -44,10 +44,16 @@
#include "llmd5.h"
#include "llstring.h"
#include "lltimer.h"
+#include "llthread.h"
const LLUUID LLUUID::null;
const LLTransactionID LLTransactionID::tnull;
+// static
+LLMutex * LLUUID::mMutex = NULL;
+
+
+
/*
NOT DONE YET!!!
@@ -734,6 +740,7 @@ void LLUUID::getCurrentTime(uuid_time_t *timestamp)
getSystemTime(&time_last);
uuids_this_tick = uuids_per_tick;
init = TRUE;
+ mMutex = new LLMutex(NULL);
}
uuid_time_t time_now = {0,0};
@@ -785,6 +792,7 @@ void LLUUID::generate()
#endif
if (!has_init)
{
+ has_init = 1;
if (getNodeID(node_id) <= 0)
{
get_random_bytes(node_id, 6);
@@ -806,18 +814,24 @@ void LLUUID::generate()
#else
clock_seq = (U16)ll_rand(65536);
#endif
- has_init = 1;
}
// get current time
getCurrentTime(&timestamp);
+ U16 our_clock_seq = clock_seq;
- // if clock went backward change clockseq
- if (cmpTime(&timestamp, &time_last) == -1) {
+ // if clock hasn't changed or went backward, change clockseq
+ if (cmpTime(&timestamp, &time_last) != 1)
+ {
+ LLMutexLock lock(mMutex);
clock_seq = (clock_seq + 1) & 0x3FFF;
- if (clock_seq == 0) clock_seq++;
+ if (clock_seq == 0)
+ clock_seq++;
+ our_clock_seq = clock_seq; // Ensure we're using a different clock_seq value from previous time
}
+ time_last = timestamp;
+
memcpy(mData+10, node_id, 6); /* Flawfinder: ignore */
U32 tmp;
tmp = timestamp.low;
@@ -839,7 +853,8 @@ void LLUUID::generate()
tmp >>= 8;
mData[6] = (unsigned char) tmp;
- tmp = clock_seq;
+ tmp = our_clock_seq;
+
mData[9] = (unsigned char) tmp;
tmp >>= 8;
mData[8] = (unsigned char) tmp;
@@ -849,8 +864,6 @@ void LLUUID::generate()
md5_uuid.update(mData,16);
md5_uuid.finalize();
md5_uuid.raw_digest(mData);
-
- time_last = timestamp;
}
void LLUUID::generate(const std::string& hash_string)
@@ -864,8 +877,14 @@ U32 LLUUID::getRandomSeed()
static unsigned char seed[16]; /* Flawfinder: ignore */
getNodeID(&seed[0]);
- seed[6]='\0';
- seed[7]='\0';
+
+ // Incorporate the pid into the seed to prevent
+ // processes that start on the same host at the same
+ // time from generating the same seed.
+ pid_t pid = LLApp::getPid();
+
+ seed[6]=(unsigned char)(pid >> 8);
+ seed[7]=(unsigned char)(pid);
getSystemTime((uuid_time_t *)(&seed[8]));
LLMD5 md5_seed;
diff --git a/indra/llcommon/lluuid.h b/indra/llcommon/lluuid.h
index 0b9e7d0cd0..7889828c85 100644
--- a/indra/llcommon/lluuid.h
+++ b/indra/llcommon/lluuid.h
@@ -31,6 +31,8 @@
#include "stdtypes.h"
#include "llpreprocessor.h"
+class LLMutex;
+
const S32 UUID_BYTES = 16;
const S32 UUID_WORDS = 4;
const S32 UUID_STR_LENGTH = 37; // actually wrong, should be 36 and use size below
@@ -118,6 +120,7 @@ public:
static BOOL validate(const std::string& in_string); // Validate that the UUID string is legal.
static const LLUUID null;
+ static LLMutex * mMutex;
static U32 getRandomSeed();
static S32 getNodeID(unsigned char * node_id);
diff --git a/indra/test/lluuidhashmap_tut.cpp b/indra/test/lluuidhashmap_tut.cpp
index 408bc3faf1..9712a613f4 100644
--- a/indra/test/lluuidhashmap_tut.cpp
+++ b/indra/test/lluuidhashmap_tut.cpp
@@ -117,9 +117,10 @@ namespace tut
std::string savefile(gDirUtilp->add(tempdir, "lluuidhashmap_tut.save.txt"));
const int numElementsToCheck = 32*256*32;
std::vector<LLUUID> idList;
- if (gDirUtilp->fileExists(savefile))
+ if ((! getenv("TEAMCITY_PROJECT_NAME")) && gDirUtilp->fileExists(savefile))
{
- // We have saved data from a previous failed run. Reload that data.
+ // This is not a TeamCity build, and we have saved data from a
+ // previous failed run. Reload that data.
std::ifstream inf(savefile.c_str());
if (! inf.is_open())
{
@@ -139,8 +140,8 @@ namespace tut
}
else
{
- // savefile does not exist (normal case): regenerate idList from
- // scratch.
+ // This is a TeamCity build, or (normal case) savefile does not
+ // exist: regenerate idList from scratch.
for (int i = 0; i < numElementsToCheck; ++i)
{
LLUUID id;