Skip Menu |

Preferred bug tracker

Please visit the preferred bug tracker to report your issue.

This queue is for tickets about the Data-UUID CPAN distribution.

Report information
The Basics
Id: 21486
Status: resolved
Worked: 5 min
Priority: 0/
Queue: Data-UUID

People
Owner: rjbs [...] cpan.org
Requestors: merijnb [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Critical
Broken in: 0.142
Fixed in: (no value)



Subject: Patch to generate unique UUIDs on fast machine (and compile on windows as a bonus)
On a fast machine using a 64 bit Perl all the uniqueness tests fail. This is a good test, added since 0.14, because before that I wasn't aware of the issue. If you construct a new Data::UUID object and ask it to create a unique UUID to quickly you will get the same one back. I haven't traced the code deeply enough yet to say if this patch is the best solution. It basically changes this line: - else if (timestamp < self->state.ts) to this one: + else if (timestamp <= self->state.ts) which means checking if the current time is before or equal to the previous time a UUID was generated. If so the clock sequence is incremented and a different UUID is generated. I've only observed this on 64bit Linux machines, but those are the fastest I have. The windows bit of the patch sorts outs the types properly, removed the second loading of unistd.h, makes the store location windows capable, makes a proper format macro for 64 bit on windows and loads the header file so pid_t and getpid will work.
Subject: Data-UUID-0.142.diff
diff -r -u /var/tmp/uuid/Data-UUID-0.142/UUID.h Data-UUID-0.142/UUID.h --- /var/tmp/uuid/Data-UUID-0.142/UUID.h 2006-09-05 22:16:06.000000000 -0400 +++ Data-UUID-0.142/UUID.h 2006-09-14 08:26:09.000000000 -0400 @@ -7,10 +7,6 @@ #ifndef WIN32 #include <unistd.h> #endif -#ifndef _MSC_VER -// No unistd.h in MS VC -#include <unistd.h> -#endif #include <time.h> #include "md5.h" @@ -35,9 +31,13 @@ #else # define PTR2ul(p) INT2PTR(unsigned long,p) #endif -#if defined __cygwin__ || __mingw32__ + + +#if defined __cygwin__ || __mingw32__ || _WIN32 #include <windows.h> +#include <process.h> #endif + #if defined __darwin__ #include <sys/file.h> #endif @@ -52,11 +52,21 @@ #define UUID_STATE ".UUID_STATE" #define UUID_NODEID ".UUID_NODEID" + +#if defined __cygwin__ || __mingw32__ || _WIN32 +#define UUID_STATE_NV_STORE _STDIR"\\"UUID_STATE +#define UUID_NODEID_NV_STORE _STDIR"\\"UUID_NODEID +#else #define UUID_STATE_NV_STORE _STDIR"/"UUID_STATE #define UUID_NODEID_NV_STORE _STDIR"/"UUID_NODEID +#endif #define UUIDS_PER_TICK 1024 +#if defined(_WIN32) +#define I64(C) C##i64 +#else #define I64(C) C##LL +#endif #define F_BIN 0 #define F_STR 1 @@ -65,16 +75,27 @@ #define CHECK(f1, f2) if (f1 != f2) RETVAL = f1 < f2 ? -1 : 1; -typedef unsigned int unsigned32; -typedef unsigned short unsigned16; -typedef unsigned char unsigned8; -typedef unsigned char byte; -#ifndef _MSC_VER -typedef unsigned long long unsigned64_t; -# else -typedef unsigned __int64 unsigned64_t; -// http://msdn2.microsoft.com/en-us/library/296az74e.aspx - Integer Limits -#endif +#if defined(_WIN32) +//types not available on windows +typedef __int64 int64_t; +typedef unsigned __int64 uint64_t; +typedef __int32 int32_t; +typedef unsigned __int32 uint32_t; +typedef __int16 int16_t; +typedef unsigned __int16 uint16_t; +typedef __int8 int8_t; +typedef unsigned __int8 uint8_t; +typedef int pid_t; +#else //SunCC or gcc +#include <inttypes.h> +#endif + +typedef uint32_t unsigned32; +typedef uint16_t unsigned16; +typedef uint8_t unsigned8; +typedef uint8_t byte; +typedef uint64_t unsigned64_t; + typedef unsigned64_t perl_uuid_time_t; #if defined __solaris__ || defined __linux__ diff -r -u /var/tmp/uuid/Data-UUID-0.142/UUID.xs Data-UUID-0.142/UUID.xs --- /var/tmp/uuid/Data-UUID-0.142/UUID.xs 2006-09-05 22:30:46.000000000 -0400 +++ Data-UUID-0.142/UUID.xs 2006-09-14 09:27:43.000000000 -0400 @@ -306,7 +306,7 @@ if ( self->state.ts == I64(0) || memcmp(&(self->nodeid), &(self->state.node), sizeof(uuid_node_t))) clockseq = true_random(); - else if (timestamp < self->state.ts) + else if (timestamp <= self->state.ts) clockseq++; format_uuid_v1(&uuid, clockseq, timestamp, self->nodeid);
On Thu Sep 14 10:21:41 2006, MERIJNB wrote: Show quoted text
> It basically changes this line: > > - else if (timestamp < self->state.ts) > > to this one: > > + else if (timestamp <= self->state.ts) >
This is only necessary when get_current_time returns the same time. But hang on, this is a function in Data::UUID with a busy wait ( a while 1 loop) to sort this out. Why is this not working? Oh, it needs this patch: --- Data-UUID-0.142-orig/UUID.xs 2006-09-05 22:30:46.000000000 -0400 +++ Data-UUID-0.142/UUID.xs 2006-09-14 12:14:14.000000000 -0400 @@ -65,6 +65,7 @@ if (time_last != time_now) { uuids_this_tick = 0; + time_last = time_now; break; }; if (uuids_this_tick < UUIDS_PER_TICK) { Either of these fixes the problem of having the same UUID in a small timespan on a fast machine. I prefer this second one, but having both is not a bad thing.
Fixed, via second patch, in 0.143; thanks very much. -- rjbs
Subject: Re: [rt.cpan.org #21486] Patch to generate unique UUIDs on fast machine (and compile on windows as a bonus)
Date: Mon, 18 Sep 2006 10:32:43 +0200
To: Ricardo Signes via RT <bug-Data-UUID [...] rt.cpan.org>
From: Merijn Broeren <merijnb [...] iloquent.com>
Quoting Ricardo Signes via RT (bug-Data-UUID@rt.cpan.org): Show quoted text
> > <URL: http://rt.cpan.org/Ticket/Display.html?id=21486 > > > > Fixed, via second patch, in 0.143; thanks very much. >
That is wonderful. Can you also take a look at the bigger patch that also fixes compilation on Windows? That would close out your other open tickets on cpan as well. Cheers, -- Merijn Broeren | Bob's guide to high explosives for dummies: | Chapter One: When the pin is pulled and safety lever | discarded, Mr. Grenade is no longer your friend.
applied in 0.145 -- rjbs