@@ -73,6 +73,7 @@ mongoc_topology_reconcile (const mongoc_topology_t *topology,
73
73
mongoc_server_description_t * sd ;
74
74
mongoc_topology_scanner_node_t * ele , * tmp ;
75
75
76
+ BSON_ASSERT (topology -> single_threaded );
76
77
servers = mc_tpld_servers (td );
77
78
/* Add newly discovered nodes */
78
79
for (size_t i = 0u ; i < servers -> items_len ; i ++ ) {
@@ -124,15 +125,16 @@ _mongoc_topology_scanner_setup_err_cb (uint32_t id,
124
125
{
125
126
mongoc_topology_t * topology = BSON_ASSERT_PTR_INLINE (data );
126
127
128
+ BSON_ASSERT (topology -> single_threaded );
127
129
if (_mongoc_topology_get_type (topology ) == MONGOC_TOPOLOGY_LOAD_BALANCED ) {
128
130
/* In load balanced mode, scanning is only for connection establishment.
129
131
* It must not modify the topology description. */
130
132
} else {
131
- /* We need to update the topology description */
132
- mc_tpld_modification mod = mc_tpld_modify_begin (topology );
133
+ // Use `mc_tpld_unsafe_get_mutable` to get a mutable topology description
134
+ // without locking. This function only applies to single-threaded clients.
135
+ mongoc_topology_description_t * td = mc_tpld_unsafe_get_mutable (topology );
133
136
mongoc_topology_description_handle_hello (
134
- mod .new_td , id , NULL /* hello reply */ , -1 /* rtt_msec */ , error );
135
- mc_tpld_modify_commit (mod );
137
+ td , id , NULL /* hello reply */ , -1 /* rtt_msec */ , error );
136
138
}
137
139
}
138
140
@@ -159,51 +161,47 @@ _mongoc_topology_scanner_cb (uint32_t id,
159
161
{
160
162
mongoc_topology_t * const topology = BSON_ASSERT_PTR_INLINE (data );
161
163
mongoc_server_description_t * sd ;
162
- mc_tpld_modification tdmod ;
164
+ mongoc_topology_description_t * td ;
163
165
166
+ BSON_ASSERT (topology -> single_threaded );
164
167
if (_mongoc_topology_get_type (topology ) == MONGOC_TOPOLOGY_LOAD_BALANCED ) {
165
168
/* In load balanced mode, scanning is only for connection establishment.
166
169
* It must not modify the topology description. */
167
170
return ;
168
171
}
169
172
170
- tdmod = mc_tpld_modify_begin (topology );
173
+ // Use `mc_tpld_unsafe_get_mutable` to get a mutable topology description
174
+ // without locking. This function only applies to single-threaded clients.
175
+ td = mc_tpld_unsafe_get_mutable (topology );
171
176
172
- sd = mongoc_topology_description_server_by_id (tdmod . new_td , id , NULL );
177
+ sd = mongoc_topology_description_server_by_id (td , id , NULL );
173
178
174
179
if (!hello_response ) {
175
180
/* Server monitoring: When a server check fails due to a network error
176
181
* (including a network timeout), the client MUST clear its connection
177
182
* pool for the server */
178
183
_mongoc_topology_description_clear_connection_pool (
179
- tdmod . new_td , id , & kZeroServiceId );
184
+ td , id , & kZeroServiceId );
180
185
}
181
186
182
187
/* Server Discovery and Monitoring Spec: "Once a server is connected, the
183
188
* client MUST change its type to Unknown only after it has retried the
184
189
* server once." */
185
190
if (!hello_response && sd && sd -> type != MONGOC_SERVER_UNKNOWN ) {
186
- _mongoc_topology_update_no_lock (
187
- id , hello_response , rtt_msec , tdmod .new_td , error );
191
+ _mongoc_topology_update_no_lock (id , hello_response , rtt_msec , td , error );
188
192
189
193
/* add another hello call to the current scan - the scan continues
190
194
* until all commands are done */
191
195
mongoc_topology_scanner_scan (topology -> scanner , sd -> id );
192
196
} else {
193
- _mongoc_topology_update_no_lock (
194
- id , hello_response , rtt_msec , tdmod .new_td , error );
197
+ _mongoc_topology_update_no_lock (id , hello_response , rtt_msec , td , error );
195
198
196
199
/* The processing of the hello results above may have added, changed, or
197
200
* removed server descriptions. We need to reconcile that with our
198
201
* monitoring agents
199
202
*/
200
- mongoc_topology_reconcile (topology , tdmod .new_td );
201
-
202
- mongoc_cond_broadcast (& topology -> cond_client );
203
+ mongoc_topology_reconcile (topology , td );
203
204
}
204
-
205
-
206
- mc_tpld_modify_commit (tdmod );
207
205
}
208
206
209
207
static void
@@ -881,7 +879,8 @@ mongoc_topology_rescan_srv (mongoc_topology_t *topology)
881
879
static void
882
880
mongoc_topology_scan_once (mongoc_topology_t * topology , bool obey_cooldown )
883
881
{
884
- mc_tpld_modification tdmod ;
882
+ mongoc_topology_description_t * td ;
883
+ BSON_ASSERT (topology -> single_threaded );
885
884
if (mongoc_topology_should_rescan_srv (topology )) {
886
885
/* Prior to scanning hosts, update the list of SRV hosts, if applicable.
887
886
*/
@@ -892,9 +891,10 @@ mongoc_topology_scan_once (mongoc_topology_t *topology, bool obey_cooldown)
892
891
* description based on hello responses in connection handshakes, see
893
892
* _mongoc_topology_update_from_handshake. retire scanner nodes for removed
894
893
* members and create scanner nodes for new ones. */
895
- tdmod = mc_tpld_modify_begin (topology );
896
- mongoc_topology_reconcile (topology , tdmod .new_td );
897
- mc_tpld_modify_commit (tdmod );
894
+ // Use `mc_tpld_unsafe_get_mutable` to get a mutable topology description
895
+ // without locking. This function only applies to single-threaded clients.
896
+ td = mc_tpld_unsafe_get_mutable (topology );
897
+ mongoc_topology_reconcile (topology , td );
898
898
899
899
mongoc_topology_scanner_start (topology -> scanner , obey_cooldown );
900
900
mongoc_topology_scanner_work (topology -> scanner );
920
920
_mongoc_topology_do_blocking_scan (mongoc_topology_t * topology ,
921
921
bson_error_t * error )
922
922
{
923
+ BSON_ASSERT (topology -> single_threaded );
923
924
_mongoc_handshake_freeze ();
924
925
925
926
mongoc_topology_scan_once (topology , true /* obey cooldown */ );
@@ -1162,9 +1163,11 @@ mongoc_topology_select_server_id (mongoc_topology_t *topology,
1162
1163
1163
1164
if (topology -> single_threaded ) {
1164
1165
if (!td .ptr -> opened ) {
1165
- mc_tpld_modification tdmod = mc_tpld_modify_begin (topology );
1166
- _mongoc_topology_description_monitor_opening (tdmod .new_td );
1167
- mc_tpld_modify_commit (tdmod );
1166
+ // Use `mc_tpld_unsafe_get_mutable` to get a mutable topology
1167
+ // description without locking. This block only applies to
1168
+ // single-threaded clients.
1169
+ _mongoc_topology_description_monitor_opening (
1170
+ mc_tpld_unsafe_get_mutable (topology ));
1168
1171
mc_tpld_renew_ref (& td , topology );
1169
1172
}
1170
1173
0 commit comments