Fix: release reference to ltt_session on error instead of free()
[lttng-tools.git] / src / bin / lttng-sessiond / session.c
index 173afa8784f47b22e7e24fbc237dbbaae70809d2..5e6488e4f28c67a98fc3bdf9cb1459fedde50fc3 100644 (file)
@@ -25,6 +25,7 @@
 #include <urcu.h>
 #include <dirent.h>
 #include <sys/types.h>
+#include <pthread.h>
 
 #include <common/common.h>
 #include <common/sessiond-comm/sessiond-comm.h>
@@ -54,6 +55,7 @@
 static struct ltt_session_list ltt_session_list = {
        .head = CDS_LIST_HEAD_INIT(ltt_session_list.head),
        .lock = PTHREAD_MUTEX_INITIALIZER,
+       .removal_cond = PTHREAD_COND_INITIALIZER,
        .next_uuid = 0,
 };
 
@@ -130,6 +132,19 @@ struct ltt_session_list *session_get_list(void)
        return &ltt_session_list;
 }
 
+/*
+ * Returns once the session list is empty.
+ */
+void session_list_wait_empty(void)
+{
+       pthread_mutex_lock(&ltt_session_list.lock);
+       while (!cds_list_empty(&ltt_session_list.head)) {
+               pthread_cond_wait(&ltt_session_list.removal_cond,
+                               &ltt_session_list.lock);
+       }
+       pthread_mutex_unlock(&ltt_session_list.lock);
+}
+
 /*
  * Acquire session list lock
  */
@@ -428,8 +443,13 @@ void session_release(struct urcu_ref *ref)
 
        consumer_output_put(session->consumer);
        snapshot_destroy(&session->snapshot);
-       del_session_list(session);
-       del_session_ht(session);
+
+       if (session->published) {
+               ASSERT_LOCKED(ltt_session_list.lock);
+               del_session_list(session);
+               del_session_ht(session);
+               pthread_cond_broadcast(&ltt_session_list.removal_cond);
+       }
        free(session);
 }
 
@@ -612,6 +632,7 @@ int session_create(char *name, uid_t uid, gid_t gid)
         * by session id.
         */
        add_session_ht(new_session);
+       new_session->published = true;
        session_unlock_list();
 
        /*
@@ -625,7 +646,9 @@ int session_create(char *name, uid_t uid, gid_t gid)
 
 error:
 error_asprintf:
-       free(new_session);
+       session_lock_list();
+       session_put(new_session);
+       session_unlock_list();
 
 error_malloc:
        return ret;
This page took 0.039797 seconds and 5 git commands to generate.