Currently the topology changed, server changed, server opening, and server closed events are called while holding the topology mutex.
This makes it easy for users to deadlock their applications by performing any operation that requires the topology mutex in those callbacks.
The same a problem exists for single threaded clients as well (since the mutex is still locked in single threaded). Here is a simple repro:
#include <mongoc/mongoc.h> #include <stdio.h> #include <stdlib.h> static void _server_changed (const mongoc_apm_server_changed_t *event) { mongoc_client_t *client; mongoc_server_description_t *sd; MONGOC_DEBUG ("server changed event - begin"); client = mongoc_apm_server_changed_get_context (event); sd = mongoc_client_select_server (client, true, NULL, NULL); mongoc_server_description_destroy (sd); MONGOC_DEBUG ("server changed event - end"); } int main (int argc, char *argv[]) { mongoc_client_t *client; mongoc_apm_callbacks_t *callbacks; mongoc_server_description_t *sd; mongoc_init (); client = mongoc_client_new ("mongodb://localhost:27017"); /* Set a server changed callback. */ callbacks = mongoc_apm_callbacks_new (); mongoc_apm_set_server_changed_cb (callbacks, _server_changed); mongoc_client_set_apm_callbacks (client, callbacks, client); sd = mongoc_client_select_server (client, true, NULL, NULL); mongoc_server_description_destroy (sd); mongoc_client_destroy (client); mongoc_apm_callbacks_destroy (callbacks); mongoc_cleanup (); }
Currently, the heartbeat events are not called while holding the topology lock.
- is related to
-
PHPC-1410 Executing commands from within an APM callback may cause deep recursion and segfault
- Backlog