Fix: baddr deadlock with lttng-ust destructor
[lttng-ust.git] / liblttng-ust / lttng-events.c
index 9380e9ceb688b9b46df58122d7cc3a47c14421b3..55d84f05efc852e444ffb48aa286435db18abf16 100644 (file)
 #include "tracepoint-internal.h"
 #include "lttng-tracer.h"
 #include "lttng-tracer-core.h"
+#include "lttng-ust-baddr.h"
 #include "wait.h"
 #include "../libringbuffer/shm.h"
 #include "jhash.h"
 
 /*
- * The sessions mutex is the centralized mutex across UST tracing
- * control and probe registration. All operations within this file are
- * called by the communication thread, under ust_lock protection.
+ * All operations within this file are called by the communication
+ * thread, under ust_lock protection.
  */
-static pthread_mutex_t sessions_mutex = PTHREAD_MUTEX_INITIALIZER;
 
-void ust_lock(void)
-{
-       pthread_mutex_lock(&sessions_mutex);
-}
+static CDS_LIST_HEAD(sessions);
 
-void ust_unlock(void)
+struct cds_list_head *_lttng_get_sessions(void)
 {
-       pthread_mutex_unlock(&sessions_mutex);
+       return &sessions;
 }
 
-static CDS_LIST_HEAD(sessions);
-
 static void _lttng_event_destroy(struct lttng_event *event);
 
 static
@@ -676,19 +670,31 @@ int lttng_fix_pending_events(void)
 }
 
 /*
- * Called after session enable: For each session, execute pending statedumps.
+ * For each session of the owner thread, execute pending statedump.
+ * Only dump state for the sessions owned by the caller thread, because
+ * we don't keep ust_lock across the entire iteration.
  */
-int lttng_handle_pending_statedumps(t_statedump_func_ptr statedump_func_ptr)
+void lttng_handle_pending_statedump(void *owner)
 {
        struct lttng_session *session;
 
+       /* Execute state dump */
+       lttng_ust_baddr_statedump(owner);
+
+       /* Clear pending state dump */
+       if (ust_lock()) {
+               goto end;
+       }
        cds_list_for_each_entry(session, &sessions, node) {
-               if (session->statedump_pending) {
-                       session->statedump_pending = 0;
-                       statedump_func_ptr(session);
-               }
+               if (session->owner != owner)
+                       continue;
+               if (!session->statedump_pending)
+                       continue;
+               session->statedump_pending = 0;
        }
-       return 0;
+end:
+       ust_unlock();
+       return;
 }
 
 /*
This page took 0.023948 seconds and 4 git commands to generate.