Skip to content

Commit d2e6be2

Browse files
authored
CDRIVER-6058 Use thread-safe pseudo-random number generator API (#2065)
1 parent 017cf32 commit d2e6be2

File tree

2 files changed

+25
-18
lines changed

2 files changed

+25
-18
lines changed

src/libmongoc/src/mongoc/mongoc-cluster.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2358,7 +2358,7 @@ mongoc_cluster_init (mongoc_cluster_t *cluster, const mongoc_uri_t *uri, void *c
23582358

23592359
_mongoc_array_init (&cluster->iov, sizeof (mongoc_iovec_t));
23602360

2361-
cluster->operation_id = rand ();
2361+
cluster->operation_id = _mongoc_simple_rand_uint64_t ();
23622362

23632363
EXIT;
23642364
}

src/libmongoc/src/mongoc/mongoc-util.c

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -854,44 +854,51 @@ _mongoc_crypto_rand_size_t (void)
854854

855855
#endif /* defined(MONGOC_ENABLE_CRYPTO) */
856856

857-
static BSON_ONCE_FUN (_mongoc_simple_rand_init)
857+
#define _mongoc_thread_local BSON_IF_GNU_LIKE (__thread) BSON_IF_MSVC (__declspec (thread))
858+
859+
// Use a thread-local random seed for calls to `rand_r`:
860+
static _mongoc_thread_local unsigned int _mongoc_simple_rand_seed = 0;
861+
static _mongoc_thread_local bool _mongoc_simple_rand_seed_initialized = false;
862+
863+
static void
864+
_mongoc_simple_rand_init (void)
858865
{
866+
if (_mongoc_simple_rand_seed_initialized) {
867+
return;
868+
}
869+
_mongoc_simple_rand_seed_initialized = true;
859870
struct timeval tv;
860-
unsigned int seed = 0;
861871

862872
bson_gettimeofday (&tv);
863873

864-
seed ^= (unsigned int) tv.tv_sec;
865-
seed ^= (unsigned int) tv.tv_usec;
866-
867-
srand (seed);
868-
869-
BSON_ONCE_RETURN;
874+
_mongoc_simple_rand_seed ^= (unsigned int) tv.tv_sec;
875+
_mongoc_simple_rand_seed ^= (unsigned int) tv.tv_usec;
870876
}
871877

872-
static bson_once_t _mongoc_simple_rand_init_once = BSON_ONCE_INIT;
873-
874878
uint32_t
875879
_mongoc_simple_rand_uint32_t (void)
876880
{
877-
bson_once (&_mongoc_simple_rand_init_once, _mongoc_simple_rand_init);
881+
_mongoc_simple_rand_init ();
878882

879883
/* Ensure *all* bits are random, as RAND_MAX is only required to be at least
880884
* 32767 (2^15). */
881-
return (((uint32_t) rand () & 0x7FFFu) << 0u) | (((uint32_t) rand () & 0x7FFFu) << 15u) |
882-
(((uint32_t) rand () & 0x0003u) << 30u);
885+
return (((uint32_t) _mongoc_rand_simple (&_mongoc_simple_rand_seed) & 0x7FFFu) << 0u) |
886+
(((uint32_t) _mongoc_rand_simple (&_mongoc_simple_rand_seed) & 0x7FFFu) << 15u) |
887+
(((uint32_t) _mongoc_rand_simple (&_mongoc_simple_rand_seed) & 0x0003u) << 30u);
883888
}
884889

885890
uint64_t
886891
_mongoc_simple_rand_uint64_t (void)
887892
{
888-
bson_once (&_mongoc_simple_rand_init_once, _mongoc_simple_rand_init);
893+
_mongoc_simple_rand_init ();
889894

890895
/* Ensure *all* bits are random, as RAND_MAX is only required to be at least
891896
* 32767 (2^15). */
892-
return (((uint64_t) rand () & 0x7FFFu) << 0u) | (((uint64_t) rand () & 0x7FFFu) << 15u) |
893-
(((uint64_t) rand () & 0x7FFFu) << 30u) | (((uint64_t) rand () & 0x7FFFu) << 45u) |
894-
(((uint64_t) rand () & 0x0003u) << 60u);
897+
return (((uint64_t) _mongoc_rand_simple (&_mongoc_simple_rand_seed) & 0x7FFFu) << 0u) |
898+
(((uint64_t) _mongoc_rand_simple (&_mongoc_simple_rand_seed) & 0x7FFFu) << 15u) |
899+
(((uint64_t) _mongoc_rand_simple (&_mongoc_simple_rand_seed) & 0x7FFFu) << 30u) |
900+
(((uint64_t) _mongoc_rand_simple (&_mongoc_simple_rand_seed) & 0x7FFFu) << 45u) |
901+
(((uint64_t) _mongoc_rand_simple (&_mongoc_simple_rand_seed) & 0x0003u) << 60u);
895902
}
896903

897904
uint32_t

0 commit comments

Comments
 (0)