common: replace container_of with a C++ safe implementation
[lttng-tools.git] / src / bin / lttng-sessiond / session.cpp
index 3dc8065569d2dfd850e7949912bc9e4dece9b3da..e9d7261031d632fc44e4f820621a8e471a3e9e74 100644 (file)
@@ -6,31 +6,34 @@
  */
 
 #define _LGPL_SOURCE
-#include <limits.h>
+#include <dirent.h>
 #include <inttypes.h>
+#include <limits.h>
+#include <pthread.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <sys/stat.h>
-#include <urcu.h>
-#include <dirent.h>
 #include <sys/types.h>
-#include <pthread.h>
+#include <urcu.h>
 
 #include <common/common.hpp>
-#include <common/utils.hpp>
-#include <common/trace-chunk.hpp>
 #include <common/sessiond-comm/sessiond-comm.hpp>
-#include <lttng/location-internal.hpp>
+#include <common/trace-chunk.hpp>
+#include <common/urcu.hpp>
+#include <common/utils.hpp>
+
 #include "lttng-sessiond.hpp"
-#include "kernel.hpp"
+#include <lttng/location-internal.hpp>
 
+#include "cmd.hpp"
+#include "kernel.hpp"
 #include "session.hpp"
-#include "utils.hpp"
-#include "trace-ust.hpp"
 #include "timer.hpp"
-#include "cmd.hpp"
+#include "trace-ust.hpp"
+#include "utils.hpp"
 
+namespace {
 struct ltt_session_destroy_notifier_element {
        ltt_session_destroy_notifier notifier;
        void *user_data;
@@ -41,6 +44,8 @@ struct ltt_session_clear_notifier_element {
        void *user_data;
 };
 
+namespace ls = lttng::sessiond;
+
 /*
  * NOTES:
  *
@@ -50,25 +55,26 @@ struct ltt_session_clear_notifier_element {
  * using session_lock() and session_unlock().
  */
 
+/* These characters are forbidden in a session name. Used by validate_name. */
+const char *forbidden_name_chars = "/";
+
+/* Global hash table to keep the sessions, indexed by id. */
+struct lttng_ht *ltt_sessions_ht_by_id = NULL;
+/* Global hash table to keep the sessions, indexed by name. */
+struct lttng_ht *ltt_sessions_ht_by_name = NULL;
+
 /*
  * Init tracing session list.
  *
  * Please see session.h for more explanation and correct usage of the list.
  */
-static struct ltt_session_list ltt_session_list = {
+struct ltt_session_list the_session_list = {
        .lock = PTHREAD_MUTEX_INITIALIZER,
        .removal_cond = PTHREAD_COND_INITIALIZER,
        .next_uuid = 0,
-       .head = CDS_LIST_HEAD_INIT(ltt_session_list.head),
+       .head = CDS_LIST_HEAD_INIT(the_session_list.head),
 };
-
-/* These characters are forbidden in a session name. Used by validate_name. */
-static const char *forbidden_name_chars = "/";
-
-/* Global hash table to keep the sessions, indexed by id. */
-static struct lttng_ht *ltt_sessions_ht_by_id = NULL;
-/* Global hash table to keep the sessions, indexed by name. */
-static struct lttng_ht *ltt_sessions_ht_by_name = NULL;
+} /* namespace */
 
 /*
  * Validate the session name for forbidden characters.
@@ -113,8 +119,8 @@ static uint64_t add_session_list(struct ltt_session *ls)
 {
        LTTNG_ASSERT(ls);
 
-       cds_list_add(&ls->list, &ltt_session_list.head);
-       return ltt_session_list.next_uuid++;
+       cds_list_add(&ls->list, &the_session_list.head);
+       return the_session_list.next_uuid++;
 }
 
 /*
@@ -134,7 +140,7 @@ static void del_session_list(struct ltt_session *ls)
  */
 struct ltt_session_list *session_get_list(void)
 {
-       return &ltt_session_list;
+       return &the_session_list;
 }
 
 /*
@@ -142,12 +148,12 @@ struct ltt_session_list *session_get_list(void)
  */
 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_lock(&the_session_list.lock);
+       while (!cds_list_empty(&the_session_list.head)) {
+               pthread_cond_wait(&the_session_list.removal_cond,
+                               &the_session_list.lock);
        }
-       pthread_mutex_unlock(&ltt_session_list.lock);
+       pthread_mutex_unlock(&the_session_list.lock);
 }
 
 /*
@@ -155,7 +161,7 @@ void session_list_wait_empty(void)
  */
 void session_lock_list(void)
 {
-       pthread_mutex_lock(&ltt_session_list.lock);
+       pthread_mutex_lock(&the_session_list.lock);
 }
 
 /*
@@ -163,7 +169,7 @@ void session_lock_list(void)
  */
 int session_trylock_list(void)
 {
-       return pthread_mutex_trylock(&ltt_session_list.lock);
+       return pthread_mutex_trylock(&the_session_list.lock);
 }
 
 /*
@@ -171,7 +177,7 @@ int session_trylock_list(void)
  */
 void session_unlock_list(void)
 {
-       pthread_mutex_unlock(&ltt_session_list.lock);
+       pthread_mutex_unlock(&the_session_list.lock);
 }
 
 /*
@@ -870,7 +876,7 @@ enum lttng_error_code session_kernel_open_packets(struct ltt_session *session)
 
        cds_lfht_first(session->kernel_session->consumer->socks->ht, &iter.iter);
        node = cds_lfht_iter_get_node(&iter.iter);
-       socket = container_of(node, typeof(*socket), node.node);
+       socket = caa_container_of(node, typeof(*socket), node.node);
 
        cds_list_for_each_entry(chan,
                        &session->kernel_session->channel_list.head, list) {
@@ -973,7 +979,7 @@ void session_release(struct urcu_ref *ref)
        int ret;
        struct ltt_ust_session *usess;
        struct ltt_kernel_session *ksess;
-       struct ltt_session *session = container_of(ref, typeof(*session), ref);
+       struct ltt_session *session = lttng::utils::container_of(ref, &ltt_session::ref);
        const bool session_published = session->published;
 
        LTTNG_ASSERT(!session->chunk_being_archived);
@@ -1015,7 +1021,7 @@ void session_release(struct urcu_ref *ref)
        pthread_mutex_destroy(&session->lock);
 
        if (session_published) {
-               ASSERT_LOCKED(ltt_session_list.lock);
+               ASSERT_LOCKED(the_session_list.lock);
                del_session_list(session);
                del_session_ht(session);
        }
@@ -1032,14 +1038,15 @@ void session_release(struct urcu_ref *ref)
        lttng_dynamic_array_reset(&session->clear_notifiers);
        free(session->last_archived_chunk_name);
        free(session->base_path);
+       lttng_trigger_put(session->rotate_trigger);
        free(session);
        if (session_published) {
                /*
                 * Broadcast after free-ing to ensure the memory is
                 * reclaimed before the main thread exits.
                 */
-               ASSERT_LOCKED(ltt_session_list.lock);
-               pthread_cond_broadcast(&ltt_session_list.removal_cond);
+               ASSERT_LOCKED(the_session_list.lock);
+               pthread_cond_broadcast(&the_session_list.removal_cond);
        }
 }
 
@@ -1064,7 +1071,7 @@ void session_put(struct ltt_session *session)
         * The session list lock must be held as any session_put()
         * may cause the removal of the session from the session_list.
         */
-       ASSERT_LOCKED(ltt_session_list.lock);
+       ASSERT_LOCKED(the_session_list.lock);
        LTTNG_ASSERT(session->ref.refcount);
        urcu_ref_put(&session->ref, session_release);
 }
@@ -1137,11 +1144,11 @@ struct ltt_session *session_find_by_name(const char *name)
        struct ltt_session *iter;
 
        LTTNG_ASSERT(name);
-       ASSERT_LOCKED(ltt_session_list.lock);
+       ASSERT_LOCKED(the_session_list.lock);
 
        DBG2("Trying to find session by name %s", name);
 
-       cds_list_for_each_entry(iter, &ltt_session_list.head, list) {
+       cds_list_for_each_entry(iter, &the_session_list.head, list) {
                if (!strncmp(iter->name, name, NAME_MAX) &&
                                !iter->destroyed) {
                        goto found;
@@ -1165,7 +1172,7 @@ struct ltt_session *session_find_by_id(uint64_t id)
        struct ltt_session *ls;
 
        ASSERT_RCU_READ_LOCKED();
-       ASSERT_LOCKED(ltt_session_list.lock);
+       ASSERT_LOCKED(the_session_list.lock);
 
        if (!ltt_sessions_ht_by_id) {
                goto end;
@@ -1176,7 +1183,7 @@ struct ltt_session *session_find_by_id(uint64_t id)
        if (node == NULL) {
                goto end;
        }
-       ls = caa_container_of(node, struct ltt_session, node);
+       ls = lttng::utils::container_of(node, &ltt_session::node);
 
        DBG3("Session %" PRIu64 " found by id.", id);
        return session_get(ls) ? ls : NULL;
@@ -1197,7 +1204,7 @@ enum lttng_error_code session_create(const char *name, uid_t uid, gid_t gid,
        enum lttng_error_code ret_code;
        struct ltt_session *new_session = NULL;
 
-       ASSERT_LOCKED(ltt_session_list.lock);
+       ASSERT_LOCKED(the_session_list.lock);
        if (name) {
                struct ltt_session *clashing_session;
 
@@ -1391,7 +1398,7 @@ int session_reset_rotation_state(struct ltt_session *session,
 {
        int ret = 0;
 
-       ASSERT_LOCKED(ltt_session_list.lock);
+       ASSERT_LOCKED(the_session_list.lock);
        ASSERT_LOCKED(session->lock);
 
        session->rotation_state = result;
@@ -1449,7 +1456,7 @@ bool sample_session_id_by_name(const char *name, uint64_t *id)
                goto end;
        }
 
-       ls = caa_container_of(node, struct ltt_session, node_by_name);
+       ls = lttng::utils::container_of(node, &ltt_session::node_by_name);
        *id = ls->id;
        found = true;
 
@@ -1458,3 +1465,38 @@ end:
        rcu_read_unlock();
        return found;
 }
+
+void ls::details::locked_session_release(ltt_session *session)
+{
+       session_unlock(session);
+       session_put(session);
+}
+
+ltt_session::locked_ptr ls::find_locked_session_by_id(ltt_session::id_t id)
+{
+       lttng::urcu::read_lock_guard rcu_lock;
+       auto session = session_find_by_id(id);
+
+       if (!session) {
+               return nullptr;
+       }
+
+       /*
+        * The pointer falling out of scope will unlock and release the reference to the
+        * session.
+        */
+       session_lock(session);
+       return ltt_session::locked_ptr(session);
+}
+
+ltt_session::sptr ls::find_session_by_id(ltt_session::id_t id)
+{
+       lttng::urcu::read_lock_guard rcu_lock;
+       auto session = session_find_by_id(id);
+
+       if (!session) {
+               return nullptr;
+       }
+
+       return {session, session_put};
+}
This page took 0.027136 seconds and 4 git commands to generate.