Skip to content

Commit 68456a9

Browse files
[CDRIVER-5605] Mitigate a race on setting APM callbacks (#1641)
1 parent c1c6783 commit 68456a9

File tree

3 files changed

+18
-13
lines changed

3 files changed

+18
-13
lines changed

src/libmongoc/src/mongoc/mongoc-client-pool.c

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -568,25 +568,30 @@ mongoc_client_pool_set_apm_callbacks (mongoc_client_pool_t *pool, mongoc_apm_cal
568568
BSON_ASSERT_PARAM (pool);
569569

570570
mongoc_topology_t *const topology = BSON_ASSERT_PTR_INLINE (pool)->topology;
571-
mc_tpld_modification tdmod;
571+
mc_tpld_modification tdmod = mc_tpld_modify_begin (topology);
572572

573+
// Prevent setting callbacks more than once
573574
if (pool->apm_callbacks_set) {
575+
mc_tpld_modify_drop (tdmod);
574576
MONGOC_ERROR ("Can only set callbacks once");
575577
return false;
576578
}
577579

578-
tdmod = mc_tpld_modify_begin (topology);
579-
580+
// Update callbacks on the pool
580581
if (callbacks) {
581-
memcpy (&tdmod.new_td->apm_callbacks, callbacks, sizeof (mongoc_apm_callbacks_t));
582-
memcpy (&pool->apm_callbacks, callbacks, sizeof (mongoc_apm_callbacks_t));
582+
pool->apm_callbacks = *callbacks;
583+
} else {
584+
pool->apm_callbacks = (mongoc_apm_callbacks_t){0};
583585
}
586+
pool->apm_context = context;
584587

588+
// Update callbacks on the topology
585589
mongoc_topology_set_apm_callbacks (topology, tdmod.new_td, callbacks, context);
586-
tdmod.new_td->apm_context = context;
587-
pool->apm_context = context;
590+
591+
// Signal that we have already set the callbacks
588592
pool->apm_callbacks_set = true;
589593

594+
// Save our updated topology
590595
mc_tpld_modify_commit (tdmod);
591596

592597
return true;

src/libmongoc/src/mongoc/mongoc-topology-private.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ mongoc_topology_new (const mongoc_uri_t *uri, bool single_threaded);
233233
void
234234
mongoc_topology_set_apm_callbacks (mongoc_topology_t *topology,
235235
mongoc_topology_description_t *td,
236-
mongoc_apm_callbacks_t *callbacks,
236+
mongoc_apm_callbacks_t const *callbacks,
237237
void *context);
238238

239239
void

src/libmongoc/src/mongoc/mongoc-topology.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -640,15 +640,15 @@ mongoc_topology_new (const mongoc_uri_t *uri, bool single_threaded)
640640
void
641641
mongoc_topology_set_apm_callbacks (mongoc_topology_t *topology,
642642
mongoc_topology_description_t *td,
643-
mongoc_apm_callbacks_t *callbacks,
643+
mongoc_apm_callbacks_t const *callbacks,
644644
void *context)
645645
{
646646
if (callbacks) {
647-
memcpy (&td->apm_callbacks, callbacks, sizeof (mongoc_apm_callbacks_t));
648-
memcpy (&topology->scanner->apm_callbacks, callbacks, sizeof (mongoc_apm_callbacks_t));
647+
td->apm_callbacks = *callbacks;
648+
topology->scanner->apm_callbacks = *callbacks;
649649
} else {
650-
memset (&td->apm_callbacks, 0, sizeof (mongoc_apm_callbacks_t));
651-
memset (&topology->scanner->apm_callbacks, 0, sizeof (mongoc_apm_callbacks_t));
650+
td->apm_callbacks = (mongoc_apm_callbacks_t){0};
651+
topology->scanner->apm_callbacks = (mongoc_apm_callbacks_t){0};
652652
}
653653

654654
td->apm_context = context;

0 commit comments

Comments
 (0)