#define _LTT_SESSION_H
#include <limits.h>
+#include <memory>
#include <stdbool.h>
#include <urcu/list.h>
-#include <common/hashtable/hashtable.hpp>
#include <common/dynamic-array.hpp>
-#include <lttng/rotation.h>
+#include <common/hashtable/hashtable.hpp>
+#include <common/make-unique-wrapper.hpp>
+#include <common/pthread-lock.hpp>
#include <lttng/location.h>
#include <lttng/lttng-error.h>
+#include <lttng/rotation.h>
+#include <lttng/trace-format-descriptor-internal.hpp>
#include "snapshot.hpp"
#include "trace-kernel.hpp"
#include "consumer.hpp"
+#define ASSERT_SESSION_LIST_LOCKED() LTTNG_ASSERT(session_trylock_list())
+
struct ltt_ust_session;
typedef void (*ltt_session_destroy_notifier)(const struct ltt_session *session,
typedef void (*ltt_session_clear_notifier)(const struct ltt_session *session,
void *user_data);
+namespace lttng {
+namespace sessiond {
+namespace details {
+void locked_session_release(ltt_session *session);
+} /* namespace details */
+} /* namespace sessiond */
+} /* namespace lttng */
+
/*
* Tracing session list
*
* session for both LTTng and UST.
*/
struct ltt_session {
- char name[NAME_MAX];
- bool has_auto_generated_name;
- bool name_contains_creation_time;
- char hostname[LTTNG_HOST_NAME_MAX]; /* Local hostname. */
+ using id_t = uint64_t;
+ using locked_ptr = std::unique_ptr<ltt_session,
+ lttng::details::create_unique_class<ltt_session,
+ lttng::sessiond::details::locked_session_release>::deleter>;
+ using sptr = std::shared_ptr<ltt_session>;
+
+ ltt_session()
+ {
+ has_been_started = 0;
+ active = 0;
+ };
+ ~ltt_session() = default;
+
+ char name[NAME_MAX]{0};
+ bool has_auto_generated_name{false};
+ bool name_contains_creation_time{false};
+ char hostname[LTTNG_HOST_NAME_MAX]{0}; /* Local hostname. */
/* Path of the last closed chunk. */
- char last_chunk_path[LTTNG_PATH_MAX];
- time_t creation_time;
- struct ltt_kernel_session *kernel_session;
- struct ltt_ust_session *ust_session;
- struct urcu_ref ref;
+ char last_chunk_path[LTTNG_PATH_MAX]{0};
+ time_t creation_time{};
+ struct ltt_kernel_session *kernel_session{};
+ struct ltt_ust_session *ust_session{};
+ struct urcu_ref ref {};
/*
* Protect any read/write on this session data structure. This lock must be
* acquired *before* using any public functions declared below. Use
* session_lock() and session_unlock() for that.
*/
- pthread_mutex_t lock;
- struct cds_list_head list;
- uint64_t id; /* session unique identifier */
+ pthread_mutex_t lock{};
+ struct cds_list_head list {};
+ id_t id{}; /* session unique identifier */
/* Indicates if the session has been added to the session list and ht.*/
- bool published;
+ bool published{false};
/* Indicates if a destroy command has been applied to this session. */
- bool destroyed;
+ bool destroyed{false};
/* UID/GID of the user owning the session */
- uid_t uid;
- gid_t gid;
+ uid_t uid{};
+ gid_t gid{};
/*
* Network session handle. A value of 0 means that there is no remote
* session established.
*/
- uint64_t net_handle;
+ uint64_t net_handle{};
/*
* This consumer is only set when the create_session_uri call is made.
* This contains the temporary information for a consumer output. Upon
* creation of the UST or kernel session, this consumer, if available, is
* copied into those sessions.
*/
- struct consumer_output *consumer;
+ struct consumer_output *consumer{};
/*
* Indicates whether or not the user has specified an output directory
* or if it was configured using the default configuration.
*/
- bool has_user_specified_directory;
+ bool has_user_specified_directory{false};
/* Did at least ONE start command has been triggered?. */
- unsigned int has_been_started:1;
+ bool has_been_started{false};
/*
- * Is the session active? Start trace command sets this to 1 and the stop
- * command reset it to 0.
+ * Is the session active? Start trace command sets this to true and the stop
+ * command reset it to false.
*/
- unsigned int active:1;
+ bool active{false};
/* Snapshot representation in a session. */
- struct snapshot snapshot;
+ struct snapshot snapshot {};
/* Indicate if the session has to output the traces or not. */
- unsigned int output_traces;
+ unsigned int output_traces{};
/*
* This session is in snapshot mode. This means that channels enabled
* will be set in overwrite mode by default and must be in mmap
* is not in "snapshot_mode". This parameter only affects channel
* creation defaults.
*/
- unsigned int snapshot_mode;
+ unsigned int snapshot_mode{};
/*
* A session that has channels that don't use 'mmap' output can't be
* used to capture snapshots. This is set to true whenever a
* 'splice' kernel channel is enabled.
*/
- bool has_non_mmap_channel;
+ bool has_non_mmap_channel{false};
/*
* Timer set when the session is created for live reading.
*/
- unsigned int live_timer;
+ unsigned int live_timer{0};
/*
* Path where to keep the shared memory files.
*/
- char shm_path[PATH_MAX];
+ char shm_path[PATH_MAX]{};
/*
* Node in ltt_sessions_ht_by_id.
*/
- struct lttng_ht_node_u64 node;
+ struct lttng_ht_node_u64 node {};
/*
* Node in ltt_sessions_ht_by_name.
*/
- struct lttng_ht_node_str node_by_name;
+ struct lttng_ht_node_str node_by_name {};
/*
* Timer to check periodically if a relay and/or consumer has completed
* the last rotation.
*/
- bool rotation_pending_check_timer_enabled;
- timer_t rotation_pending_check_timer;
+ bool rotation_pending_check_timer_enabled{false};
+ timer_t rotation_pending_check_timer{};
/* Timer to periodically rotate a session. */
- bool rotation_schedule_timer_enabled;
- timer_t rotation_schedule_timer;
+ bool rotation_schedule_timer_enabled{false};
+ timer_t rotation_schedule_timer{};
/* Value for periodic rotations, 0 if disabled. */
- uint64_t rotate_timer_period;
+ uint64_t rotate_timer_period{};
/* Value for size-based rotations, 0 if disabled. */
- uint64_t rotate_size;
+ uint64_t rotate_size{};
/*
* Keep a state if this session was rotated after the last stop command.
* We only allow one rotation after a stop. At destroy, we also need to
* chunk. After a stop followed by rotate, all subsequent clear
* (without prior start) will succeed, but will be effect-less.
*/
- bool rotated_after_last_stop;
+ bool rotated_after_last_stop{false};
/*
* Track whether the session was cleared after last stop. All subsequent
* clear (without prior start) will succeed, but will be effect-less. A
* subsequent rotate (without prior start) will return an error.
*/
- bool cleared_after_last_stop;
+ bool cleared_after_last_stop{false};
/*
* True if the session has had an explicit non-quiet rotation.
*/
- bool rotated;
+ bool rotated{false};
/*
- * Condition and trigger for size-based rotations.
+ * Trigger for size-based rotations.
*/
- struct lttng_condition *rotate_condition;
- struct lttng_trigger *rotate_trigger;
- LTTNG_OPTIONAL(uint64_t) most_recent_chunk_id;
- struct lttng_trace_chunk *current_trace_chunk;
- struct lttng_trace_chunk *chunk_being_archived;
+ struct lttng_trigger *rotate_trigger{};
+ LTTNG_OPTIONAL(uint64_t) most_recent_chunk_id{};
+ struct lttng_trace_chunk *current_trace_chunk{};
+ struct lttng_trace_chunk *chunk_being_archived{};
/* Current state of a rotation. */
- enum lttng_rotation_state rotation_state;
- bool quiet_rotation;
- char *last_archived_chunk_name;
- LTTNG_OPTIONAL(uint64_t) last_archived_chunk_id;
- struct lttng_dynamic_array destroy_notifiers;
- struct lttng_dynamic_array clear_notifiers;
+ enum lttng_rotation_state rotation_state { LTTNG_ROTATION_STATE_NO_ROTATION };
+ bool quiet_rotation{false};
+ char *last_archived_chunk_name{};
+ LTTNG_OPTIONAL(uint64_t) last_archived_chunk_id{};
+ struct lttng_dynamic_array destroy_notifiers {};
+ struct lttng_dynamic_array clear_notifiers {};
/* Session base path override. Set non-null. */
- char *base_path;
+ char *base_path{};
+ /* Trace output format */
+ lttng::trace_format_descriptor::sptr trace_format;
};
-enum lttng_error_code session_create(const char *name, uid_t uid, gid_t gid,
+enum lttng_error_code session_create(const char *name,
+ uid_t uid,
+ gid_t gid,
+ lttng::trace_format_descriptor::uptr& trace_format,
struct ltt_session **out_session);
void session_lock(struct ltt_session *session);
void session_unlock(struct ltt_session *session);
const struct ltt_session *session);
struct ltt_session *session_find_by_name(const char *name);
-struct ltt_session *session_find_by_id(uint64_t id);
+struct ltt_session *session_find_by_id(ltt_session::id_t id);
struct ltt_session_list *session_get_list(void);
void session_list_wait_empty(void);
*/
bool sample_session_id_by_name(const char *name, uint64_t *id);
+namespace lttng {
+namespace sessiond {
+
+/*
+ * Session list lock must be acquired by the caller.
+ * The caller must not keep the ownership of the returned locked session
+ * for longer than strictly necessary. If your intention is to acquire
+ * a reference to an ltt_session, see `find_session_by_id()`.
+ */
+ltt_session::locked_ptr find_locked_session_by_id(ltt_session::id_t id);
+
+/*
+ * Session list lock must be acquired by the caller.
+ * The caller must not keep the ownership of the returned locked session
+ * for longer than strictly necessary. If your intention is to acquire
+ * a reference to an ltt_session, see `find_session_by_id()`.
+ */
+ltt_session::sptr find_session_by_id(ltt_session::id_t id);
+
+} /* namespace sessiond */
+} /* namespace lttng */
+
#endif /* _LTT_SESSION_H */