summaryrefslogtreecommitdiff
path: root/cpp/src/IceUtil/UUID.cpp
diff options
context:
space:
mode:
authorBenoit Foucher <benoit@zeroc.com>2006-03-23 12:57:11 +0000
committerBenoit Foucher <benoit@zeroc.com>2006-03-23 12:57:11 +0000
commit07ec4897c353261f24b53b7a48d0694e91fabc9e (patch)
tree21999efbc960b13bf6ddefa141be7e05dbd5a27d /cpp/src/IceUtil/UUID.cpp
parentChanges for TAO 1.5 (diff)
downloadice-07ec4897c353261f24b53b7a48d0694e91fabc9e.tar.bz2
ice-07ec4897c353261f24b53b7a48d0694e91fabc9e.tar.xz
ice-07ec4897c353261f24b53b7a48d0694e91fabc9e.zip
Added Random.cpp
Diffstat (limited to 'cpp/src/IceUtil/UUID.cpp')
-rw-r--r--cpp/src/IceUtil/UUID.cpp143
1 files changed, 13 insertions, 130 deletions
diff --git a/cpp/src/IceUtil/UUID.cpp b/cpp/src/IceUtil/UUID.cpp
index afd99eaf55f..169dcf32eef 100644
--- a/cpp/src/IceUtil/UUID.cpp
+++ b/cpp/src/IceUtil/UUID.cpp
@@ -17,11 +17,7 @@
#ifdef _WIN32
# include <rpc.h>
#else
-# include <IceUtil/StaticMutex.h>
-# include <sys/types.h>
-# include <sys/stat.h>
-# include <fcntl.h>
-# include <unistd.h>
+# include <IceUtil/Random.h>
#endif
using namespace std;
@@ -49,75 +45,6 @@ inline void bytesToHex(unsigned char* bytes, size_t len, char*& hexBuffer)
}
}
-
-IceUtil::UUIDGenerationException::UUIDGenerationException(const char* file, int line) :
- Exception(file, line)
-{
-}
-
-const char* IceUtil::UUIDGenerationException::_name = "IceUtil::UUIDGenerationException";
-
-#ifndef _WIN32
-//
-// Unfortunately on Linux (at least up to 2.6.9), concurrent access to /dev/urandom
-// can return the same value. Search for "Concurrent access to /dev/urandom" in the
-// linux-kernel mailing list archive for additional details.
-// Since /dev/urandom on other platforms is usually a port from Linux, this problem
-// could be widespread. Therefore, instead of using 122 random bits that could be
-// duplicated, we replace the last 15 bits of all "random" UUIDs by the last 15 bits
-// of the process id, and in each process, we serialize access to /dev/urandom using
-// a static mutex.
-//
-
-static IceUtil::StaticMutex staticMutex = ICE_STATIC_MUTEX_INITIALIZER;
-static int fd = -1;
-static char myPid[2];
-
-namespace
-{
-
-//
-// Close fd at exit
-//
-class UUIDCleanup
-{
-public:
-
- ~UUIDCleanup()
- {
- IceUtil::StaticMutex::Lock lock(staticMutex);
- if(fd != -1)
- {
- close(fd);
- fd = -1;
- }
- }
-};
-static UUIDCleanup uuidCleanup;
-}
-
-
-#endif
-
-const string
-IceUtil::UUIDGenerationException::ice_name() const
-{
- return _name;
-}
-
-IceUtil::Exception*
-IceUtil::UUIDGenerationException::ice_clone() const
-{
- return new UUIDGenerationException(*this);
-}
-
-void
-IceUtil::UUIDGenerationException::ice_throw() const
-{
- throw *this;
-}
-
-
string
IceUtil::generateUUID()
{
@@ -149,62 +76,18 @@ IceUtil::generateUUID()
assert(sizeof(UUID) == 16);
+ //
+ // Get a random sequence of bytes and the pid of the current
+ // process. Instead of using 122 random bits that could be
+ // duplicated (because of a bug with some Linux kernels and
+ // potentially other Unix platforms -- see comment in Random.cpp),
+ // we replace the last 15 bits of all "random" Randoms by the last
+ // 15 bits of the process id.
+ //
char* buffer = reinterpret_cast<char*>(&uuid);
- int reads = 0;
- size_t index = 0;
+ char pid[2];
+ generateRandomAndGetPid(buffer, sizeof(UUID), pid);
- {
- //
- // Serialize access to /dev/urandom; see comment above.
- //
- IceUtil::StaticMutex::Lock lock(staticMutex);
- if(fd == -1)
- {
- fd = open("/dev/urandom", O_RDONLY);
- if (fd == -1)
- {
- assert(0);
- throw UUIDGenerationException(__FILE__, __LINE__);
- }
-
- //
- // Initialize myPid as well
- //
- pid_t pid = getpid();
- myPid[0] = (pid >> 8) & 0x7F;
- myPid[1] = pid & 0xFF;
- }
-
-
- //
- // Limit the number of attempts to 20 reads to avoid
- // a potential "for ever" loop
- //
- while(reads <= 20 && index != sizeof(UUID))
- {
- ssize_t bytesRead = read(fd, buffer + index, sizeof(UUID) - index);
-
- if(bytesRead == -1 && errno != EINTR)
- {
- int err = errno;
- cerr << "Reading /dev/urandom returned " << strerror(err) << endl;
- assert(0);
- throw UUIDGenerationException(__FILE__, __LINE__);
- }
- else
- {
- index += bytesRead;
- reads++;
- }
- }
- }
-
- if (index != sizeof(UUID))
- {
- assert(0);
- throw UUIDGenerationException(__FILE__, __LINE__);
- }
-
//
// Adjust the bits that say "version 4" UUID
//
@@ -216,8 +99,8 @@ IceUtil::generateUUID()
//
// Replace the end of the node by myPid (15 bits)
//
- uuid.node[4] = (uuid.node[4] & 0x80) | myPid[0];
- uuid.node[5] = myPid[1];
+ uuid.node[4] = (uuid.node[4] & 0x80) | pid[0];
+ uuid.node[5] = pid[1];
//
// Convert to a UUID string