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

Commitc941aed

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 parent25dd07e commitc941aed

File tree

1 file changed

+45
-31
lines changed

1 file changed

+45
-31
lines changed

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

Lines changed: 45 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,42 @@ pguuid_complain(uuid_rc_t rc)
141141
errmsg("OSSP uuid library failure: error code %d",rc)));
142142
}
143143

144+
/*
145+
* We create a uuid_t object just once per session and re-use it for all
146+
* operations in this module. OSSP UUID caches the system MAC address and
147+
* other state in this object. Reusing the object has a number of benefits:
148+
* saving the cycles needed to fetch the system MAC address over and over,
149+
* reducing the amount of entropy we draw from /dev/urandom, and providing a
150+
* positive guarantee that successive generated V1-style UUIDs don't collide.
151+
* (On a machine fast enough to generate multiple UUIDs per microsecond,
152+
* or whatever the system's wall-clock resolution is, we'd otherwise risk
153+
* collisions whenever random initialization of the uuid_t's clock sequence
154+
* value chanced to produce duplicates.)
155+
*
156+
* However: when we're doing V3 or V5 UUID creation, uuid_make needs two
157+
* uuid_t objects, one holding the namespace UUID and one for the result.
158+
* It's unspecified whether it's safe to use the same uuid_t for both cases,
159+
* so let's cache a second uuid_t for use as the namespace holder object.
160+
*/
161+
staticuuid_t*
162+
get_cached_uuid_t(intwhich)
163+
{
164+
staticuuid_t*cached_uuid[2]= {NULL,NULL};
165+
166+
if (cached_uuid[which]==NULL)
167+
{
168+
uuid_rc_trc;
169+
170+
rc=uuid_create(&cached_uuid[which]);
171+
if (rc!=UUID_RC_OK)
172+
{
173+
cached_uuid[which]=NULL;
174+
pguuid_complain(rc);
175+
}
176+
}
177+
returncached_uuid[which];
178+
}
179+
144180
staticchar*
145181
uuid_to_string(constuuid_t*uuid)
146182
{
@@ -171,20 +207,14 @@ string_to_uuid(const char *str, uuid_t *uuid)
171207
staticDatum
172208
special_uuid_value(constchar*name)
173209
{
174-
uuid_t*uuid;
210+
uuid_t*uuid=get_cached_uuid_t(0);
175211
char*str;
176212
uuid_rc_trc;
177213

178-
rc=uuid_create(&uuid);
179-
if (rc!=UUID_RC_OK)
180-
pguuid_complain(rc);
181214
rc=uuid_load(uuid,name);
182215
if (rc!=UUID_RC_OK)
183216
pguuid_complain(rc);
184217
str=uuid_to_string(uuid);
185-
rc=uuid_destroy(uuid);
186-
if (rc!=UUID_RC_OK)
187-
pguuid_complain(rc);
188218

189219
returnDirectFunctionCall1(uuid_in,CStringGetDatum(str));
190220
}
@@ -193,20 +223,14 @@ special_uuid_value(const char *name)
193223
staticDatum
194224
uuid_generate_internal(intmode,constuuid_t*ns,constchar*name,intlen)
195225
{
196-
uuid_t*uuid;
226+
uuid_t*uuid=get_cached_uuid_t(0);
197227
char*str;
198228
uuid_rc_trc;
199229

200-
rc=uuid_create(&uuid);
201-
if (rc!=UUID_RC_OK)
202-
pguuid_complain(rc);
203230
rc=uuid_make(uuid,mode,ns,name);
204231
if (rc!=UUID_RC_OK)
205232
pguuid_complain(rc);
206233
str=uuid_to_string(uuid);
207-
rc=uuid_destroy(uuid);
208-
if (rc!=UUID_RC_OK)
209-
pguuid_complain(rc);
210234

211235
returnDirectFunctionCall1(uuid_in,CStringGetDatum(str));
212236
}
@@ -215,26 +239,16 @@ uuid_generate_internal(int mode, const uuid_t *ns, const char *name, int len)
215239
staticDatum
216240
uuid_generate_v35_internal(intmode,pg_uuid_t*ns,text*name)
217241
{
218-
uuid_t*ns_uuid;
219-
Datumresult;
220-
uuid_rc_trc;
242+
uuid_t*ns_uuid=get_cached_uuid_t(1);
221243

222-
rc=uuid_create(&ns_uuid);
223-
if (rc!=UUID_RC_OK)
224-
pguuid_complain(rc);
225-
string_to_uuid(DatumGetCString(DirectFunctionCall1(uuid_out,UUIDPGetDatum(ns))),
244+
string_to_uuid(DatumGetCString(DirectFunctionCall1(uuid_out,
245+
UUIDPGetDatum(ns))),
226246
ns_uuid);
227247

228-
result=uuid_generate_internal(mode,
229-
ns_uuid,
230-
text_to_cstring(name),
231-
0);
232-
233-
rc=uuid_destroy(ns_uuid);
234-
if (rc!=UUID_RC_OK)
235-
pguuid_complain(rc);
236-
237-
returnresult;
248+
returnuuid_generate_internal(mode,
249+
ns_uuid,
250+
text_to_cstring(name),
251+
0);
238252
}
239253

240254
#else/* !HAVE_UUID_OSSP */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp