common: replace container_of with a C++ safe implementation
[lttng-tools.git] / src / bin / lttng-relayd / session.cpp
index 5fa39663a5a63fc80fbc024509278d88aea988f0..6e29fbc741afd1efe32723f7342f8cc809fa9a3c 100644 (file)
@@ -8,23 +8,23 @@
  */
 
 #define _LGPL_SOURCE
-#include <common/common.h>
-#include <common/compat/path.h>
-#include <common/fd-tracker/utils.h>
-#include <common/time.h>
-#include <common/utils.h>
-#include <common/uuid.h>
+#include <common/common.hpp>
+#include <common/compat/path.hpp>
+#include <common/fd-tracker/utils.hpp>
+#include <common/time.hpp>
+#include <common/utils.hpp>
+#include <common/uuid.hpp>
 #include <urcu/rculist.h>
 
 #include <sys/stat.h>
 
-#include "ctf-trace.h"
-#include "lttng-relayd.h"
-#include "session.h"
-#include "sessiond-trace-chunks.h"
-#include "stream.h"
-#include <common/defaults.h>
-#include "utils.h"
+#include "ctf-trace.hpp"
+#include "lttng-relayd.hpp"
+#include "session.hpp"
+#include "sessiond-trace-chunks.hpp"
+#include "stream.hpp"
+#include <common/defaults.hpp>
+#include "utils.hpp"
 
 /* Global session id used in the session creation. */
 static uint64_t last_relay_session_id;
@@ -281,7 +281,7 @@ struct relay_session *session_create(const char *session_name,
                const char *hostname, const char *base_path,
                uint32_t live_timer,
                bool snapshot,
-               const lttng_uuid sessiond_uuid,
+               const lttng_uuid& sessiond_uuid,
                const uint64_t *id_sessiond,
                const uint64_t *current_chunk_id,
                const time_t *creation_time,
@@ -310,7 +310,7 @@ struct relay_session *session_create(const char *session_name,
                goto error;
        }
 
-       session = (relay_session *) zmalloc(sizeof(*session));
+       session = zmalloc<relay_session>();
        if (!session) {
                PERROR("Failed to allocate session");
                goto error;
@@ -363,7 +363,7 @@ struct relay_session *session_create(const char *session_name,
 
        session->live_timer = live_timer;
        session->snapshot = snapshot;
-       lttng_uuid_copy(session->sessiond_uuid, sessiond_uuid);
+       session->sessiond_uuid = sessiond_uuid;
 
        if (id_sessiond) {
                LTTNG_OPTIONAL_SET(&session->id_sessiond, *id_sessiond);
@@ -464,7 +464,7 @@ struct relay_session *session_get_by_id(uint64_t id)
                DBG("Session find by ID %" PRIu64 " id NOT found", id);
                goto end;
        }
-       session = caa_container_of(node, struct relay_session, session_n);
+       session = lttng::utils::container_of(node, &relay_session::session_n);
        DBG("Session find by ID %" PRIu64 " id found", id);
        if (!session_get(session)) {
                session = NULL;
@@ -474,6 +474,90 @@ end:
        return session;
 }
 
+/*
+ * Check if any of the relay sessions originating from the same
+ * session daemon session have the 'ongoing_rotation' state set.
+ *
+ * The caller must hold the lock of session.
+ */
+bool session_has_ongoing_rotation(const struct relay_session *session)
+{
+       bool ongoing_rotation = false;
+       struct lttng_ht_iter iter;
+       struct relay_session *iterated_session;
+
+       ASSERT_LOCKED(session->lock);
+
+       if (!session->id_sessiond.is_set) {
+               /*
+                * The peer that created this session is too old to
+                * support rotations; we can assume no rotations are ongoing.
+                */
+               goto end;
+       }
+
+       if (session->ongoing_rotation) {
+               ongoing_rotation = true;
+               goto end;
+       }
+
+       rcu_read_lock();
+       /*
+        * Sample the 'ongoing_rotation' status of all relay sessions that
+        * originate from the same session daemon session.
+        */
+       cds_lfht_for_each_entry(sessions_ht->ht, &iter.iter, iterated_session,
+                       session_n.node) {
+               if (!session_get(iterated_session)) {
+                       continue;
+               }
+
+               if (session == iterated_session) {
+                       /* Skip this session. */
+                       goto next_session_no_unlock;
+               }
+
+               pthread_mutex_lock(&iterated_session->lock);
+
+               if (!iterated_session->id_sessiond.is_set) {
+                       /*
+                        * Session belongs to a peer that doesn't support
+                        * rotations.
+                        */
+                       goto next_session;
+               }
+
+               if (session->sessiond_uuid != iterated_session->sessiond_uuid) {
+                       /* Sessions do not originate from the same sessiond. */
+                       goto next_session;
+               }
+
+               if (LTTNG_OPTIONAL_GET(session->id_sessiond) !=
+                               LTTNG_OPTIONAL_GET(iterated_session->id_sessiond)) {
+                       /*
+                        * Sessions do not originate from the same sessiond
+                        * session.
+                        */
+                       goto next_session;
+               }
+
+               ongoing_rotation = iterated_session->ongoing_rotation;
+
+next_session:
+               pthread_mutex_unlock(&iterated_session->lock);
+next_session_no_unlock:
+               session_put(iterated_session);
+
+               if (ongoing_rotation) {
+                       break;
+               }
+       }
+       rcu_read_unlock();
+
+end:
+       return ongoing_rotation;
+}
+
 static void rcu_destroy_session(struct rcu_head *rcu_head)
 {
        struct relay_session *session =
@@ -525,7 +609,7 @@ static void destroy_session(struct relay_session *session)
 static void session_release(struct urcu_ref *ref)
 {
        struct relay_session *session =
-                       caa_container_of(ref, struct relay_session, ref);
+                       lttng::utils::container_of(ref, &relay_session::ref);
 
        destroy_session(session);
 }
This page took 0.029282 seconds and 4 git commands to generate.