diff options
author | yamuna <yamuna@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2003-07-01 03:47:32 +0000 |
---|---|---|
committer | yamuna <yamuna@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2003-07-01 03:47:32 +0000 |
commit | 12480d7935cf06f8738f97e4bbe98b1a7e411b94 (patch) | |
tree | 54167958409a654d46bb64459c5cb4c935536c61 | |
parent | 4a7a3f8556b01426bfc38cd0666451a17b87ad35 (diff) | |
download | ATCD-12480d7935cf06f8738f97e4bbe98b1a7e411b94.tar.gz |
*** empty log message ***
-rw-r--r-- | ace/UUID.cpp | 205 | ||||
-rw-r--r-- | ace/UUID.h | 52 |
2 files changed, 200 insertions, 57 deletions
diff --git a/ace/UUID.cpp b/ace/UUID.cpp index 83a6893cb15..d976a55be57 100644 --- a/ace/UUID.cpp +++ b/ace/UUID.cpp @@ -51,6 +51,8 @@ ACE_UUID::ACE_UUID (const ACE_UUID::UUID_t &uuid) ACE_UUID::ACE_UUID (const ACE_SString& uuid_string) : uuid_ (nil_uuid_t) { + ACE_TRACE ("ACE_UUID::ACE_UUID"); + if (uuid_string.length() != NIL_UUID.to_string()->length()) { ACE_DEBUG ((LM_DEBUG, @@ -123,14 +125,14 @@ ACE_UUID::ACE_UUID (const ACE_SString& uuid_string) uuid_.timeLow = ACE_static_cast (ACE_UINT32, timeLow); uuid_.timeMid = ACE_static_cast (ACE_UINT16, timeMid); uuid_.timeHiAndVersion = ACE_static_cast (ACE_UINT16, timeHiAndVersion); - uuid_.clockSeqHiAndReserved = ACE_static_cast (Octet , clockSeqHiAndReserved); - uuid_.clockSeqLow = ACE_static_cast (Octet , clockSeqLow); - uuid_.node.nodeID[0] = ACE_static_cast (Octet , node[0]); - uuid_.node.nodeID[1] = ACE_static_cast (Octet , node[1]); - uuid_.node.nodeID[2] = ACE_static_cast (Octet , node[2]); - uuid_.node.nodeID[3] = ACE_static_cast (Octet , node[3]); - uuid_.node.nodeID[4] = ACE_static_cast (Octet , node[4]); - uuid_.node.nodeID[5] = ACE_static_cast (Octet , node[5]); + uuid_.clockSeqHiAndReserved = ACE_static_cast (u_char , clockSeqHiAndReserved); + uuid_.clockSeqLow = ACE_static_cast (u_char , clockSeqLow); + uuid_.node.nodeID[0] = ACE_static_cast (u_char , node[0]); + uuid_.node.nodeID[1] = ACE_static_cast (u_char , node[1]); + uuid_.node.nodeID[2] = ACE_static_cast (u_char , node[2]); + uuid_.node.nodeID[3] = ACE_static_cast (u_char , node[3]); + uuid_.node.nodeID[4] = ACE_static_cast (u_char , node[4]); + uuid_.node.nodeID[5] = ACE_static_cast (u_char , node[5]); // Support varient 10- only if ((uuid_.clockSeqHiAndReserved & 0xc0) != 0x80) @@ -164,25 +166,29 @@ ACE_UUID::to_string (void) // Note. It would be nice to use ACE_SStringstream for this. But, for // compatability with gcc we must used std::sprintf. Fix this when all // supported platforms implement ACE_SStringstream. - + // Get a buffer exactly the correct size. Use the nil UUID as a gauge. // Don't forget the trailing nul. - const int UUID_STRING_LENGTH = 36 + 2 * sizeof (ACE_UINT16) + 2; - char buf [UUID_STRING_LENGTH + 1]; + int UUID_STRING_LENGTH = 36 + uuid_.thr_id->length () + uuid_.pid->length () + 2; + //char buf [UUID_STRING_LENGTH + 1]; + char *buf; + ACE_NEW_RETURN (buf, + char[UUID_STRING_LENGTH + 1], + 0); /** * We know that the node id is 6 in length as we define it and so does the * standard. */ ACE_OS::sprintf(buf, - "%8.8x-%4.4x-%4.4x-%2.2x%2.2x-%4.4x-%4.4x-%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x", + "%8.8x-%4.4x-%4.4x-%2.2x%2.2x-%s-%s-%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x", uuid_.timeLow, uuid_.timeMid, uuid_.timeHiAndVersion, uuid_.clockSeqHiAndReserved, uuid_.clockSeqLow, - uuid_.thr_id, - uuid_.pid, + uuid_.thr_id->c_str (), + uuid_.pid->c_str (), uuid_.node.nodeID[0], uuid_.node.nodeID[1], uuid_.node.nodeID[2], @@ -203,8 +209,9 @@ ACE_UUID::to_string (void) // return ACE_Singleton< ACE_UUID_Generator, ACE_SYNCH_MUTEX >::instance(); // } -ACE_UUID_Generator::ACE_UUID_Generator() - : timeLast(0) +ACE_UUID_Generator::ACE_UUID_Generator(void) + : timeLast(0), + lock_ (0) { ACE_OS::macaddr_node_t macaddress; @@ -230,18 +237,67 @@ ACE_UUID_Generator::ACE_UUID_Generator() { // Generate random node. This is pretty bad, but until // ACE has a strong prng, this is what we can do. - uuid_state_.node.nodeID[0] = static_cast<Octet>(ACE_OS::rand()); - uuid_state_.node.nodeID[1] = static_cast<Octet>(ACE_OS::rand()); - uuid_state_.node.nodeID[2] = static_cast<Octet>(ACE_OS::rand()); - uuid_state_.node.nodeID[3] = static_cast<Octet>(ACE_OS::rand()); - uuid_state_.node.nodeID[4] = static_cast<Octet>(ACE_OS::rand()); - uuid_state_.node.nodeID[5] = static_cast<Octet>(ACE_OS::rand()); + uuid_state_.node.nodeID[0] = static_cast<u_char>(ACE_OS::rand()); + uuid_state_.node.nodeID[1] = static_cast<u_char>(ACE_OS::rand()); + uuid_state_.node.nodeID[2] = static_cast<u_char>(ACE_OS::rand()); + uuid_state_.node.nodeID[3] = static_cast<u_char>(ACE_OS::rand()); + uuid_state_.node.nodeID[4] = static_cast<u_char>(ACE_OS::rand()); + uuid_state_.node.nodeID[5] = static_cast<u_char>(ACE_OS::rand()); } getTimestamp(timeLast); uuid_state_.timestamp = timeLast; } +ACE_UUID_Generator::ACE_UUID_Generator(ACE_Lock* lock) + : timeLast(0), + lock_ (lock) +{ + + ACE_OS::macaddr_node_t macaddress; + int result = + ACE_OS::getmacaddress (&macaddress); + + if (result != -1) + { + ACE_DEBUG ((LM_DEBUG, + "%02X-%02X-%02X-%02X-%02X-%02X\n", + macaddress.node [0], + macaddress.node [1], + macaddress.node [2], + macaddress.node [3], + macaddress.node [4], + macaddress.node [5])); + + ACE_OS::memcpy (uuid_state_.node.nodeID, + macaddress.node, + sizeof (uuid_state_.node.nodeID)); + } + else + { + // Generate random node. This is pretty bad, but until + // ACE has a strong prng, this is what we can do. + uuid_state_.node.nodeID[0] = static_cast<u_char>(ACE_OS::rand()); + uuid_state_.node.nodeID[1] = static_cast<u_char>(ACE_OS::rand()); + uuid_state_.node.nodeID[2] = static_cast<u_char>(ACE_OS::rand()); + uuid_state_.node.nodeID[3] = static_cast<u_char>(ACE_OS::rand()); + uuid_state_.node.nodeID[4] = static_cast<u_char>(ACE_OS::rand()); + uuid_state_.node.nodeID[5] = static_cast<u_char>(ACE_OS::rand()); + } + + if (lock_ != 0) + { + ACE_GUARD (ACE_Lock, mon, *lock_); + getTimestamp(timeLast); + uuid_state_.timestamp = timeLast; + } + else + { + getTimestamp(timeLast); + uuid_state_.timestamp = timeLast; + } +} + ACE_UUID_Generator::~ACE_UUID_Generator() { } @@ -253,39 +309,37 @@ ACE_UUID_Generator::generateV1(ACE_UUID::UUID_t& uuid) getTimestamp(timestamp); // Construct a Version 1 UUID with the information in the arguements. - uuid.timeLow = static_cast<ACE_UINT32> (timestamp & 0xFFFFFFFF); - uuid.timeMid = static_cast<ACE_UINT16> ((timestamp >> 32) & 0xFFFF); - uuid.timeHiAndVersion = static_cast<ACE_UINT16> ((timestamp >> 48) & 0xFFFF); + uuid.timeLow = ACE_static_cast (ACE_UINT32, timestamp & 0xFFFFFFFF); + uuid.timeMid = ACE_static_cast(ACE_UINT16, (timestamp >> 32) & 0xFFFF); + uuid.timeHiAndVersion = ACE_static_cast (ACE_UINT16, (timestamp >> 48) & 0xFFFF); uuid.timeHiAndVersion |= (1 << 12); uuid.clockSeqLow = uuid_state_.clockSequence & 0xFF; uuid.clockSeqHiAndReserved = (uuid_state_.clockSequence & 0x3f00) >> 8; uuid.clockSeqHiAndReserved |= 0x80; uuid.node = uuid_state_.node; -#if defined (ACE_HAS_PTHREADS) || defined (ACE_WIN32) - ACE_thread_t thr_id = ACE_OS::thr_self (); ACE_hthread_t thr_handle; ACE_OS::thr_self (thr_handle); ACE_Thread_ID thread_id (thr_id, thr_handle); - uuid.thr_id = thr_id; -char buf [BUFSIZ]; + char buf [BUFSIZ]; thread_id.to_string (buf); - ACE_DEBUG ((LM_DEBUG, - "%s\n", - buf)); - -#endif - pid_t pid = ACE_OS::getpid (); - uuid.pid = pid; - /* - ACE_OS::sprintf (uuid.pid, + uuid.thr_id = new ACE_CString (buf); + + ACE_OS::sprintf (buf, "%d", - pid); - */ + ACE_static_cast (int, ACE_OS::getpid ())); + + uuid.pid = new ACE_CString (buf); - uuid_state_.timestamp = timestamp; + if (lock_ != 0) + { + ACE_GUARD (ACE_Lock, mon, *lock_); + uuid_state_.timestamp = timestamp; + } + else + uuid_state_.timestamp = timestamp; } ACE_UUID @@ -296,6 +350,7 @@ ACE_UUID_Generator::generateUUID () return uuid; } +/* void ACE_UUID_Generator::getTimestamp( UUID_time_t& timestamp) { @@ -324,6 +379,51 @@ ACE_UUID_Generator::getTimestamp( UUID_time_t& timestamp) timestamp = timeNow + uuidsThisTick; } +*/ + +/** + * Obtain a new timestamp. If UUID's are being generated + * to quickly this method will 'spin' until enough time + * has elapsed. + */ +void +ACE_UUID_Generator::getTimestamp ( UUID_time_t& timestamp) +{ + this->get_system_time(timestamp); + + /** + * Account for the clock being set back. Increment the clock sequence. + */ + if (timestamp <= time_last_) + { + if (lock_ != 0) + { + ACE_GUARD (ACE_Lock, mon, *lock_); + uuid_state_.clockSequence = (uuid_state_.clockSequence + 1) & ACE_UUID_CLOCK_SEQ_MASK; + } + else + { + uuid_state_.clockSequence = (uuid_state_.clockSequence + 1) & ACE_UUID_CLOCK_SEQ_MASK; + } + } + /** + * If the system time ticked since the last UUID was generated. Set the clock sequence back. + */ + else if (timestamp > time_last_) + { + if (lock_ != 0) + { + ACE_GUARD (ACE_Lock, mon, *lock_); + uuid_state_.clockSequence = 0; + } + else + { + uuid_state_.clockSequence = 0; + } + } + + time_last_ = timestamp; +} /** * ACE_Time_Value is in POSIX time, seconds since Jan 1, 1970. UUIDs use @@ -336,6 +436,7 @@ ACE_UUID_Generator::getTimestamp( UUID_time_t& timestamp) * This adds up, in days: (17+30+31+365*17+4)+(365*300+73)+(365*70+17) or * 122192928000000000U (0x1B21DD213814000) 100 ns ticks. */ +/* void ACE_UUID_Generator::get_system_time (UUID_time_t& timestamp) { @@ -346,6 +447,28 @@ ACE_UUID_Generator::get_system_time (UUID_time_t& timestamp) UUID_time_t time = now.sec() * 10000000 + now.usec() * 10; timestamp = time + timeOffset; } +*/ +/** + * ACE_Time_Value is in POSIX time, seconds since Jan 1, 1970. UUIDs use + * time in 100ns ticks since 15 October 1582. The difference is: + * 15 Oct 1582 - 1 Jan 1600: 17 days in Oct, 30 in Nov, 31 in Dec + + * 17 years and 4 leap days (1584, 88, 92 and 96) + * 1 Jan 1600 - 1 Jan 1900: 3 centuries + 73 leap days ( 25 in 17th cent. + * and 24 each in 18th and 19th centuries) + * 1 Jan 1900 - 1 Jan 1970: 70 years + 17 leap days. + * This adds up, in days: (17+30+31+365*17+4)+(365*300+73)+(365*70+17) or + * 122192928000000000U (0x1B21DD213814000) 100 ns ticks. +*/ +void +ACE_UUID_Generator::get_system_time(UUID_time_t& timestamp) +{ + const UUID_time_t timeOffset = 0x1B21DD213814000; + + // Get the time of day, convert to 100ns ticks then add the offset. + ACE_Time_Value now = ACE_OS::gettimeofday(); + UUID_time_t time = now.sec() * 10000000 + now.usec() * 10; + timestamp = time + timeOffset; +} #if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) template class ACE_Singleton<ACE_UUID_Generator, ACE_SYNCH_MUTEX>; diff --git a/ace/UUID.h b/ace/UUID.h index 4f966dd7766..f972aaed8fc 100644 --- a/ace/UUID.h +++ b/ace/UUID.h @@ -7,7 +7,8 @@ #include "ace/SString.h" #include "ace/Singleton.h" -typedef unsigned char Octet; +//typedef unsigned char Octet; +class ACE_Lock; /** * @class ACE_UUID @@ -38,8 +39,8 @@ class ACE_Export ACE_UUID */ struct UUID_node_t { - typedef enum { NODE_ID_SIZE = 6 } ; - typedef Octet NodeID[NODE_ID_SIZE]; + typedef enum {NODE_ID_SIZE = 6}; + typedef u_char NodeID[NODE_ID_SIZE]; bool operator == (const UUID_node_t& right) const; bool operator != (const UUID_node_t& right) const; bool operator < (const UUID_node_t& right) const; @@ -52,11 +53,11 @@ class ACE_Export ACE_UUID ACE_UINT32 timeLow; ACE_UINT16 timeMid; ACE_UINT16 timeHiAndVersion; - Octet clockSeqHiAndReserved; - Octet clockSeqLow; - ACE_UINT16 thr_id; - ACE_UINT32 pid; - UUID_node_t node; + u_char clockSeqHiAndReserved; + u_char clockSeqLow; + ACE_CString* thr_id; + ACE_CString* pid; + UUID_node_t node; }; ACE_UUID(void); @@ -127,13 +128,13 @@ class ACE_Export ACE_UUID_Generator { public: - //static ACE_UUID_Generator* instance(); - + enum { ACE_UUID_CLOCK_SEQ_MASK = 0x3FFF }; + // Format timestamp, clockseq, and nodeID into a VI UUID. void generateV1(ACE_UUID::UUID_t&); // Format timestamp, clockseq, and nodeID into a VI UUID. - ACE_UUID generateUUID (); + ACE_UUID generateUUID (void); /** * Type to represent UTC as a count of 100 nanosecond intervals since @@ -141,14 +142,25 @@ class ACE_Export ACE_UUID_Generator */ typedef ACE_UINT64 UUID_time_t; - ACE_UUID_Generator(); + ACE_UUID_Generator(void); + ACE_UUID_Generator(ACE_Lock* lock); ~ACE_UUID_Generator(); - private: + + /** + * The locking strategy prevents multiple generators + * from accessing the UUID_state at the same time. + * Get the locking strategy. + */ + ACE_Lock *lock (void); + + /** + * Set a new locking strategy and return the hold one. + */ + ACE_Lock *lock (ACE_Lock *lock); - //friend class ACE_Singleton< ACE_UUID_Generator, ACE_SYNCH_MUTEX >; - + private: /** * The maximum number of uuids that can be generated per tick of the @@ -191,18 +203,26 @@ class ACE_Export ACE_UUID_Generator * the Christian calendar). */ void get_system_time( UUID_time_t& timeNow); + /** + * The system time when that last uuid was generated. + */ + UUID_time_t time_last_; + + /** * The UUID generator persistent state. */ UUID_state uuid_state_; + + ACE_Lock* lock_; // No value semantics //ACE_UNIMPLEMENTED_FUNC (ACE_UUID_Generator( const ACE_UUID_Generator&)) // ACE_UNIMPLEMENTED_FUNC (ACE_UUID_Generator& operator=( const ACE_UUID_Generator&)) }; -typedef ACE_Singleton <ACE_UUID_Generator, ACE_Thread_Mutex> ACE_UUID_GENERATOR; +typedef ACE_Singleton <ACE_UUID_Generator, ACE_SYNCH_MUTEX> ACE_UUID_GENERATOR; #if defined (__ACE_INLINE__) #include "ace/UUID.i" |