Uploaded image for project: 'C Driver'
  1. C Driver
  2. CDRIVER-3658

SDAM events deadlock if user callback tries to lock topology mutex

    • Type: Icon: Bug Bug
    • Resolution: Unresolved
    • Priority: Icon: Major - P3 Major - P3
    • None
    • Affects Version/s: None
    • Component/s: docs, libmongoc, SDAM
    • Labels:
      None

      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.

            Assignee:
            Unassigned Unassigned
            Reporter:
            kevin.albertson@mongodb.com Kevin Albertson
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated: