Skip to content

Commit 4e01162

Browse files
committed
Fix: Duplicate UUIDs generated in forked processes
1 parent 181d9be commit 4e01162

File tree

3 files changed

+42
-5
lines changed

3 files changed

+42
-5
lines changed

ext/php_cassandra.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,8 @@ static PHP_GINIT_FUNCTION(cassandra)
273273
{
274274
uv_once(&log_once, php_cassandra_log_initialize);
275275

276-
cassandra_globals->uuid_gen = cass_uuid_gen_new();
276+
cassandra_globals->uuid_gen = NULL;
277+
cassandra_globals->uuid_gen_pid = 0;
277278
cassandra_globals->persistent_clusters = 0;
278279
cassandra_globals->persistent_sessions = 0;
279280
PHP5TO7_ZVAL_UNDEF(cassandra_globals->type_varchar);
@@ -297,7 +298,9 @@ static PHP_GINIT_FUNCTION(cassandra)
297298

298299
static PHP_GSHUTDOWN_FUNCTION(cassandra)
299300
{
300-
cass_uuid_gen_free(cassandra_globals->uuid_gen);
301+
if (cassandra_globals->uuid_gen) {
302+
cass_uuid_gen_free(cassandra_globals->uuid_gen);
303+
}
301304
php_cassandra_log_cleanup();
302305
}
303306

ext/php_cassandra.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,19 @@
3838
#include <Zend/zend_exceptions.h>
3939
#include <Zend/zend_interfaces.h>
4040

41+
#ifdef HAVE_SYS_TYPES_H
42+
#include <sys/types.h>
43+
#endif
44+
45+
#ifdef HAVE_UNISTD_H
46+
#include <unistd.h>
47+
#endif
48+
49+
#ifdef PHP_WIN32
50+
typedef int pid_t;
51+
#include <process.h>
52+
#endif
53+
4154
#if PHP_VERSION_ID < 50304
4255
# error PHP 5.3.4 or later is required in order to build the driver
4356
#endif
@@ -478,6 +491,7 @@ PHP_MINFO_FUNCTION(cassandra);
478491

479492
ZEND_BEGIN_MODULE_GLOBALS(cassandra)
480493
CassUuidGen *uuid_gen;
494+
pid_t uuid_gen_pid;
481495
unsigned int persistent_clusters;
482496
unsigned int persistent_sessions;
483497
php5to7_zval type_varchar;

ext/util/uuid_gen.c

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,20 +20,40 @@
2020

2121
ZEND_EXTERN_MODULE_GLOBALS(cassandra)
2222

23+
static CassUuidGen* get_uuid_gen() {
24+
/* Create a new uuid generator if our PID has changed. This prevents the same
25+
* UUIDs from being generated in forked processes.
26+
*/
27+
if (CASSANDRA_G(uuid_gen_pid) != getpid()) {
28+
if (CASSANDRA_G(uuid_gen)) {
29+
cass_uuid_gen_free(CASSANDRA_G(uuid_gen));
30+
}
31+
CASSANDRA_G(uuid_gen) = cass_uuid_gen_new();
32+
CASSANDRA_G(uuid_gen_pid) = getpid();
33+
}
34+
return CASSANDRA_G(uuid_gen);
35+
}
36+
2337
void
2438
php_cassandra_uuid_generate_random(CassUuid *out TSRMLS_DC)
2539
{
26-
cass_uuid_gen_random(CASSANDRA_G(uuid_gen), out);
40+
CassUuidGen* uuid_gen = get_uuid_gen();
41+
if (!uuid_gen) return;
42+
cass_uuid_gen_random(uuid_gen, out);
2743
}
2844

2945
void
3046
php_cassandra_uuid_generate_time(CassUuid *out TSRMLS_DC)
3147
{
32-
cass_uuid_gen_time(CASSANDRA_G(uuid_gen), out);
48+
CassUuidGen* uuid_gen = get_uuid_gen();
49+
if (!uuid_gen) return;
50+
cass_uuid_gen_time(uuid_gen, out);
3351
}
3452

3553
void
3654
php_cassandra_uuid_generate_from_time(long timestamp, CassUuid *out TSRMLS_DC)
3755
{
38-
cass_uuid_gen_from_time(CASSANDRA_G(uuid_gen), (cass_uint64_t) timestamp, out);
56+
CassUuidGen* uuid_gen = get_uuid_gen();
57+
if (!uuid_gen) return;
58+
cass_uuid_gen_from_time(uuid_gen, (cass_uint64_t) timestamp, out);
3959
}

0 commit comments

Comments
 (0)