Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitb2f6754

Browse files
committed
When using the OSSP UUID library, cache its uuid_t state object.
The original coding in contrib/uuid-ossp created and destroyed a uuid_tobject (or, in some cases, even two of them) each time it was called.This is not the intended usage: you're supposed to keep the uuid_t objectaround so that the library can cache its state across uses. (Other UUIDlibraries seem to keep equivalent state behind-the-scenes in staticvariables, but OSSP chose differently.) Aside from being quite inefficient,creating a new uuid_t loses knowledge of the previously generated UUID,which in theory could result in duplicate V1-style UUIDs being createdon sufficiently fast machines.On at least some platforms, creating a new uuid_t also draws some entropyfrom /dev/urandom, leaving less for the rest of the system. This seemssufficiently unpleasant to justify back-patching this change.
1 parent534cce2 commitb2f6754

File tree

1 file changed

+44
-30
lines changed

1 file changed

+44
-30
lines changed

‎contrib/uuid-ossp/uuid-ossp.c

Lines changed: 44 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,42 @@ pguuid_complain(uuid_rc_t rc)
7979
errmsg("OSSP uuid library failure: error code %d",rc)));
8080
}
8181

82+
/*
83+
* We create a uuid_t object just once per session and re-use it for all
84+
* operations in this module. OSSP UUID caches the system MAC address and
85+
* other state in this object. Reusing the object has a number of benefits:
86+
* saving the cycles needed to fetch the system MAC address over and over,
87+
* reducing the amount of entropy we draw from /dev/urandom, and providing a
88+
* positive guarantee that successive generated V1-style UUIDs don't collide.
89+
* (On a machine fast enough to generate multiple UUIDs per microsecond,
90+
* or whatever the system's wall-clock resolution is, we'd otherwise risk
91+
* collisions whenever random initialization of the uuid_t's clock sequence
92+
* value chanced to produce duplicates.)
93+
*
94+
* However: when we're doing V3 or V5 UUID creation, uuid_make needs two
95+
* uuid_t objects, one holding the namespace UUID and one for the result.
96+
* It's unspecified whether it's safe to use the same uuid_t for both cases,
97+
* so let's cache a second uuid_t for use as the namespace holder object.
98+
*/
99+
staticuuid_t*
100+
get_cached_uuid_t(intwhich)
101+
{
102+
staticuuid_t*cached_uuid[2]= {NULL,NULL};
103+
104+
if (cached_uuid[which]==NULL)
105+
{
106+
uuid_rc_trc;
107+
108+
rc=uuid_create(&cached_uuid[which]);
109+
if (rc!=UUID_RC_OK)
110+
{
111+
cached_uuid[which]=NULL;
112+
pguuid_complain(rc);
113+
}
114+
}
115+
returncached_uuid[which];
116+
}
117+
82118
staticchar*
83119
uuid_to_string(constuuid_t*uuid)
84120
{
@@ -109,20 +145,14 @@ string_to_uuid(const char *str, uuid_t *uuid)
109145
staticDatum
110146
special_uuid_value(constchar*name)
111147
{
112-
uuid_t*uuid;
148+
uuid_t*uuid=get_cached_uuid_t(0);
113149
char*str;
114150
uuid_rc_trc;
115151

116-
rc=uuid_create(&uuid);
117-
if (rc!=UUID_RC_OK)
118-
pguuid_complain(rc);
119152
rc=uuid_load(uuid,name);
120153
if (rc!=UUID_RC_OK)
121154
pguuid_complain(rc);
122155
str=uuid_to_string(uuid);
123-
rc=uuid_destroy(uuid);
124-
if (rc!=UUID_RC_OK)
125-
pguuid_complain(rc);
126156

127157
returnDirectFunctionCall1(uuid_in,CStringGetDatum(str));
128158
}
@@ -166,20 +196,14 @@ uuid_ns_x500(PG_FUNCTION_ARGS)
166196
staticDatum
167197
uuid_generate_internal(intmode,constuuid_t*ns,constchar*name)
168198
{
169-
uuid_t*uuid;
199+
uuid_t*uuid=get_cached_uuid_t(0);
170200
char*str;
171201
uuid_rc_trc;
172202

173-
rc=uuid_create(&uuid);
174-
if (rc!=UUID_RC_OK)
175-
pguuid_complain(rc);
176203
rc=uuid_make(uuid,mode,ns,name);
177204
if (rc!=UUID_RC_OK)
178205
pguuid_complain(rc);
179206
str=uuid_to_string(uuid);
180-
rc=uuid_destroy(uuid);
181-
if (rc!=UUID_RC_OK)
182-
pguuid_complain(rc);
183207

184208
returnDirectFunctionCall1(uuid_in,CStringGetDatum(str));
185209
}
@@ -202,25 +226,15 @@ uuid_generate_v1mc(PG_FUNCTION_ARGS)
202226
staticDatum
203227
uuid_generate_v35_internal(intmode,pg_uuid_t*ns,text*name)
204228
{
205-
uuid_t*ns_uuid;
206-
Datumresult;
207-
uuid_rc_trc;
229+
uuid_t*ns_uuid=get_cached_uuid_t(1);
208230

209-
rc=uuid_create(&ns_uuid);
210-
if (rc!=UUID_RC_OK)
211-
pguuid_complain(rc);
212-
string_to_uuid(DatumGetCString(DirectFunctionCall1(uuid_out,UUIDPGetDatum(ns))),
231+
string_to_uuid(DatumGetCString(DirectFunctionCall1(uuid_out,
232+
UUIDPGetDatum(ns))),
213233
ns_uuid);
214234

215-
result=uuid_generate_internal(mode,
216-
ns_uuid,
217-
text_to_cstring(name));
218-
219-
rc=uuid_destroy(ns_uuid);
220-
if (rc!=UUID_RC_OK)
221-
pguuid_complain(rc);
222-
223-
returnresult;
235+
returnuuid_generate_internal(mode,
236+
ns_uuid,
237+
text_to_cstring(name));
224238
}
225239

226240

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp