/*
* Get the session's consumer destination type.
- *
- * The caller must hold the session lock.
*/
-enum consumer_dst_type session_get_consumer_destination_type(const struct ltt_session *session)
+enum consumer_dst_type session_get_consumer_destination_type(const ltt_session::locked_ref& session)
{
/*
* The output information is duplicated in both of those session types.
/*
* Get the session's consumer network hostname.
* The caller must ensure that the destination is of type "net".
- *
- * The caller must hold the session lock.
*/
-const char *session_get_net_consumer_hostname(const struct ltt_session *session)
+const char *session_get_net_consumer_hostname(const ltt_session::locked_ref& session)
{
const char *hostname = nullptr;
const struct consumer_output *output;
/*
* Get the session's consumer network control and data ports.
* The caller must ensure that the destination is of type "net".
- *
- * The caller must hold the session lock.
*/
-void session_get_net_consumer_ports(const struct ltt_session *session,
+void session_get_net_consumer_ports(const ltt_session::locked_ref& session,
uint16_t *control_port,
uint16_t *data_port)
{
/*
* Get the location of the latest trace archive produced by a rotation.
- *
- * The caller must hold the session lock.
*/
struct lttng_trace_archive_location *
-session_get_trace_archive_location(const struct ltt_session *session)
+session_get_trace_archive_location(const ltt_session::locked_ref& session)
{
int ret;
struct lttng_trace_archive_location *location = nullptr;
session->unlock();
}
-void ltt_session::_const_session_unlock(const ltt_session &session)
+void ltt_session::_const_session_unlock(const ltt_session& session)
{
pthread_mutex_unlock(&session._lock);
}
-static int _session_set_trace_chunk_no_lock_check(struct ltt_session *session,
+static int _session_set_trace_chunk_no_lock_check(const ltt_session::locked_ref& session,
struct lttng_trace_chunk *new_trace_chunk,
struct lttng_trace_chunk **_current_trace_chunk)
{
}
struct lttng_trace_chunk *
-session_create_new_trace_chunk(const struct ltt_session *session,
+session_create_new_trace_chunk(const ltt_session::locked_ref& session,
const struct consumer_output *consumer_output_override,
const char *session_base_path_override,
const char *chunk_name_override)
goto end;
}
-int session_close_trace_chunk(struct ltt_session *session,
+int session_close_trace_chunk(const ltt_session::locked_ref& session,
struct lttng_trace_chunk *trace_chunk,
enum lttng_trace_chunk_command_type close_command,
char *closed_trace_chunk_path)
* daemon as the same "offset" in a metadata stream will no longer point
* to the same content.
*/
-static enum lttng_error_code session_kernel_open_packets(struct ltt_session *session)
+static enum lttng_error_code session_kernel_open_packets(const ltt_session::locked_ref& session)
{
enum lttng_error_code ret = LTTNG_OK;
struct consumer_socket *socket;
return ret;
}
-enum lttng_error_code session_open_packets(struct ltt_session *session)
+enum lttng_error_code session_open_packets(const ltt_session::locked_ref& session)
{
enum lttng_error_code ret = LTTNG_OK;
*
* Must be called with the session lock held.
*/
-int session_set_trace_chunk(struct ltt_session *session,
+int session_set_trace_chunk(const ltt_session::locked_ref& session,
struct lttng_trace_chunk *new_trace_chunk,
struct lttng_trace_chunk **current_trace_chunk)
{
session, new_trace_chunk, current_trace_chunk);
}
-static void session_notify_destruction(const struct ltt_session *session)
+static void session_notify_destruction(const ltt_session::locked_ref& session)
{
size_t i;
- const size_t count = lttng_dynamic_array_get_count(&session->destroy_notifiers);
+ const auto count = lttng_dynamic_array_get_count(&session->destroy_notifiers);
for (i = 0; i < count; i++) {
const struct ltt_session_destroy_notifier_element *element =
/*
* Fire each clear notifier once, and remove them from the array.
*/
-void session_notify_clear(ltt_session& session)
+void session_notify_clear(const ltt_session::locked_ref& session)
{
size_t i;
- const size_t count = lttng_dynamic_array_get_count(&session.clear_notifiers);
+ const auto count = lttng_dynamic_array_get_count(&session->clear_notifiers);
for (i = 0; i < count; i++) {
const struct ltt_session_clear_notifier_element *element =
(ltt_session_clear_notifier_element *) lttng_dynamic_array_get_element(
- &session.clear_notifiers, i);
+ &session->clear_notifiers, i);
- element->notifier(&session, element->user_data);
+ element->notifier(session, element->user_data);
}
- lttng_dynamic_array_clear(&session.clear_notifiers);
+ lttng_dynamic_array_clear(&session->clear_notifiers);
}
static void session_release(struct urcu_ref *ref)
snapshot_destroy(&session->snapshot);
- pthread_mutex_destroy(&session->_lock);
-
if (session_published) {
ASSERT_SESSION_LIST_LOCKED();
del_session_list(session);
del_session_ht(session);
}
- session_notify_destruction(session);
+
+ /*
+ * The notifiers make use of free-functions that expect a locked reference to a session.
+ * To create such a reference, we need to acquire the lock and acquire a reference (increase
+ * the ref-count). To ensure the release of the reference does not re-cross the zero value,
+ * set the refcount to a tombstone value.
+ */
+ session->ref_count.refcount = 0xDEAD5E55;
+ session_notify_destruction([session]() {
+ session_lock(session);
+ session_get(session);
+ return ltt_session::locked_ref(*session);
+ }());
+
+ pthread_mutex_destroy(&session->_lock);
consumer_output_put(session->consumer);
kernel_free_session(ksess);
session_put(session);
}
-int session_add_destroy_notifier(struct ltt_session *session,
+int session_add_destroy_notifier(const ltt_session::locked_ref& session,
ltt_session_destroy_notifier notifier,
void *user_data)
{
return lttng_dynamic_array_add_element(&session->destroy_notifiers, &element);
}
-int session_add_clear_notifier(struct ltt_session *session,
+int session_add_clear_notifier(const ltt_session::locked_ref& session,
ltt_session_clear_notifier notifier,
void *user_data)
{
* Check if the UID matches the session. Root user has access to all
* sessions.
*/
-bool session_access_ok(struct ltt_session *session, uid_t uid)
+bool session_access_ok(const ltt_session::locked_ref& session, uid_t uid)
{
- LTTNG_ASSERT(session);
return (uid == session->uid) || uid == 0;
}
*
* Must be called with the session and session_list locks held.
*/
-int session_reset_rotation_state(ltt_session& session, enum lttng_rotation_state result)
+int session_reset_rotation_state(const ltt_session::locked_ref& session,
+ enum lttng_rotation_state result)
{
int ret = 0;
ASSERT_SESSION_LIST_LOCKED();
- ASSERT_LOCKED(session._lock);
- session.rotation_state = result;
- if (session.rotation_pending_check_timer_enabled) {
+ session->rotation_state = result;
+ if (session->rotation_pending_check_timer_enabled) {
ret = timer_session_rotation_pending_check_stop(session);
}
- if (session.chunk_being_archived) {
+ if (session->chunk_being_archived) {
uint64_t chunk_id;
enum lttng_trace_chunk_status chunk_status;
- chunk_status = lttng_trace_chunk_get_id(session.chunk_being_archived, &chunk_id);
+ chunk_status = lttng_trace_chunk_get_id(session->chunk_being_archived, &chunk_id);
LTTNG_ASSERT(chunk_status == LTTNG_TRACE_CHUNK_STATUS_OK);
- LTTNG_OPTIONAL_SET(&session.last_archived_chunk_id, chunk_id);
- lttng_trace_chunk_put(session.chunk_being_archived);
- session.chunk_being_archived = nullptr;
+ LTTNG_OPTIONAL_SET(&session->last_archived_chunk_id, chunk_id);
+ lttng_trace_chunk_put(session->chunk_being_archived);
+ session->chunk_being_archived = nullptr;
/*
* Fire the clear reply notifiers if we are completing a clear
* rotation.
* session.
*/
session_lock(session);
- return ltt_session::locked_ref(session);
+ return ltt_session::locked_ref(*session);
}
ltt_session::locked_ref ltt_session::find_locked_session(lttng::c_string_view name)
}
session_lock(session);
- return ltt_session::locked_ref(session);
+ return ltt_session::locked_ref(*session);
}
ltt_session::const_locked_ref ltt_session::find_locked_const_session(ltt_session::id_t id)
}
session_lock(session);
- return ltt_session::const_locked_ref(session);
+ return ltt_session::const_locked_ref(*session);
}
ltt_session::const_locked_ref ltt_session::find_locked_const_session(lttng::c_string_view name)
}
session_lock(session);
- return ltt_session::const_locked_ref(session);
+ return ltt_session::const_locked_ref(*session);
}
ltt_session::ref ltt_session::find_session(ltt_session::id_t id)
LTTNG_THROW_SESSION_NOT_FOUND_BY_ID_ERROR(id);
}
- return ltt_session::ref(session);
+ return ltt_session::ref(*session);
}
ltt_session::ref ltt_session::find_session(lttng::c_string_view name)
LTTNG_THROW_SESSION_NOT_FOUND_BY_NAME_ERROR(name.data());
}
- return ltt_session::ref(session);
+ return ltt_session::ref(*session);
}
ltt_session::const_ref ltt_session::find_const_session(ltt_session::id_t id)
LTTNG_THROW_SESSION_NOT_FOUND_BY_ID_ERROR(id);
}
- return ltt_session::const_ref(session);
+ return ltt_session::const_ref(*session);
}
ltt_session::const_ref ltt_session::find_const_session(lttng::c_string_view name)
LTTNG_THROW_SESSION_NOT_FOUND_BY_NAME_ERROR(name.data());
}
- return ltt_session::const_ref(session);
+ return ltt_session::const_ref(*session);
}
void ltt_session::_const_session_put(const ltt_session *session)