Use compiler-agnostic defines to silence warning
[lttng-tools.git] / src / bin / lttng-sessiond / ust-app.cpp
index 684dec8690e0a2b0dc86fa618ca7f679975afd37..802b593dcb2c0b9e888afe5557b1ee97791f1c41 100644 (file)
 #include "lttng-ust-ctl.hpp"
 #include "lttng-ust-error.hpp"
 #include "notification-thread-commands.hpp"
 #include "lttng-ust-ctl.hpp"
 #include "lttng-ust-error.hpp"
 #include "notification-thread-commands.hpp"
-#include "rotate.hpp"
 #include "session.hpp"
 #include "ust-app.hpp"
 #include "ust-consumer.hpp"
 #include "session.hpp"
 #include "ust-app.hpp"
 #include "ust-consumer.hpp"
-#include "ust-field-convert.hpp"
+#include "ust-field-quirks.hpp"
 #include "utils.hpp"
 
 #include <common/bytecode/bytecode.hpp>
 #include "utils.hpp"
 
 #include <common/bytecode/bytecode.hpp>
@@ -33,6 +32,7 @@
 #include <common/format.hpp>
 #include <common/hashtable/utils.hpp>
 #include <common/make-unique.hpp>
 #include <common/format.hpp>
 #include <common/hashtable/utils.hpp>
 #include <common/make-unique.hpp>
+#include <common/pthread-lock.hpp>
 #include <common/sessiond-comm/sessiond-comm.hpp>
 #include <common/urcu.hpp>
 
 #include <common/sessiond-comm/sessiond-comm.hpp>
 #include <common/urcu.hpp>
 
@@ -66,7 +66,7 @@ struct lttng_ht *ust_app_ht;
 struct lttng_ht *ust_app_ht_by_sock;
 struct lttng_ht *ust_app_ht_by_notify_sock;
 
 struct lttng_ht *ust_app_ht_by_sock;
 struct lttng_ht *ust_app_ht_by_notify_sock;
 
-static int ust_app_flush_app_session(struct ust_app *app, struct ust_app_session *ua_sess);
+static int ust_app_flush_app_session(ust_app& app, ust_app_session& ua_sess);
 
 /* Next available channel key. Access under next_channel_key_lock. */
 static uint64_t _next_channel_key;
 
 /* Next available channel key. Access under next_channel_key_lock. */
 static uint64_t _next_channel_key;
@@ -76,8 +76,6 @@ static pthread_mutex_t next_channel_key_lock = PTHREAD_MUTEX_INITIALIZER;
 static uint64_t _next_session_id;
 static pthread_mutex_t next_session_id_lock = PTHREAD_MUTEX_INITIALIZER;
 
 static uint64_t _next_session_id;
 static pthread_mutex_t next_session_id_lock = PTHREAD_MUTEX_INITIALIZER;
 
-namespace {
-
 /*
  * Return the session registry according to the buffer type of the given
  * session.
 /*
  * Return the session registry according to the buffer type of the given
  * session.
@@ -85,28 +83,28 @@ namespace {
  * A registry per UID object MUST exists before calling this function or else
  * it LTTNG_ASSERT() if not found. RCU read side lock must be acquired.
  */
  * A registry per UID object MUST exists before calling this function or else
  * it LTTNG_ASSERT() if not found. RCU read side lock must be acquired.
  */
-static lsu::registry_session *get_session_registry(const struct ust_app_session *ua_sess)
+lsu::registry_session *ust_app_get_session_registry(const ust_app_session::identifier& ua_sess_id)
 {
        lsu::registry_session *registry = nullptr;
 
 {
        lsu::registry_session *registry = nullptr;
 
-       LTTNG_ASSERT(ua_sess);
-
-       switch (ua_sess->buffer_type) {
-       case LTTNG_BUFFER_PER_PID:
+       switch (ua_sess_id.allocation_policy) {
+       case ust_app_session::identifier::buffer_allocation_policy::PER_PID:
        {
        {
-               struct buffer_reg_pid *reg_pid = buffer_reg_pid_find(ua_sess->id);
+               struct buffer_reg_pid *reg_pid = buffer_reg_pid_find(ua_sess_id.id);
                if (!reg_pid) {
                        goto error;
                }
                registry = reg_pid->registry->reg.ust;
                break;
        }
                if (!reg_pid) {
                        goto error;
                }
                registry = reg_pid->registry->reg.ust;
                break;
        }
-       case LTTNG_BUFFER_PER_UID:
+       case ust_app_session::identifier::buffer_allocation_policy::PER_UID:
        {
        {
-               struct buffer_reg_uid *reg_uid =
-                       buffer_reg_uid_find(ua_sess->tracing_id,
-                                           ua_sess->bits_per_long,
-                                           lttng_credentials_get_uid(&ua_sess->real_credentials));
+               struct buffer_reg_uid *reg_uid = buffer_reg_uid_find(
+                       ua_sess_id.session_id,
+                       ua_sess_id.abi == ust_app_session::identifier::application_abi::ABI_32 ?
+                               32 :
+                               64,
+                       lttng_credentials_get_uid(&ua_sess_id.app_credentials));
                if (!reg_uid) {
                        goto error;
                }
                if (!reg_uid) {
                        goto error;
                }
@@ -121,14 +119,16 @@ error:
        return registry;
 }
 
        return registry;
 }
 
-lsu::registry_session::locked_ptr get_locked_session_registry(const struct ust_app_session *ua_sess)
+namespace {
+lsu::registry_session::locked_ref
+get_locked_session_registry(const ust_app_session::identifier& identifier)
 {
 {
-       auto session = get_session_registry(ua_sess);
+       auto session = ust_app_get_session_registry(identifier);
        if (session) {
                pthread_mutex_lock(&session->_lock);
        }
 
        if (session) {
                pthread_mutex_lock(&session->_lock);
        }
 
-       return lsu::registry_session::locked_ptr{ session };
+       return lsu::registry_session::locked_ref{ session };
 }
 } /* namespace */
 
 }
 } /* namespace */
 
@@ -179,16 +179,11 @@ static void copy_channel_attr_to_ustctl(struct lttng_ust_ctl_consumer_channel_at
  */
 static int ht_match_ust_app_event(struct cds_lfht_node *node, const void *_key)
 {
  */
 static int ht_match_ust_app_event(struct cds_lfht_node *node, const void *_key)
 {
-       struct ust_app_event *event;
-       const struct ust_app_ht_key *key;
-       int ev_loglevel_value;
-
        LTTNG_ASSERT(node);
        LTTNG_ASSERT(_key);
 
        LTTNG_ASSERT(node);
        LTTNG_ASSERT(_key);
 
-       event = caa_container_of(node, struct ust_app_event, node.node);
-       key = (ust_app_ht_key *) _key;
-       ev_loglevel_value = event->attr.loglevel;
+       auto *event = lttng_ht_node_container_of(node, &ust_app_event::node);
+       const auto *key = (ust_app_ht_key *) _key;
 
        /* Match the 4 elements of the key: name, filter, loglevel, exclusions */
 
 
        /* Match the 4 elements of the key: name, filter, loglevel, exclusions */
 
@@ -198,18 +193,12 @@ static int ht_match_ust_app_event(struct cds_lfht_node *node, const void *_key)
        }
 
        /* Event loglevel. */
        }
 
        /* Event loglevel. */
-       if (ev_loglevel_value != key->loglevel_type) {
-               if (event->attr.loglevel_type == LTTNG_UST_ABI_LOGLEVEL_ALL &&
-                   key->loglevel_type == 0 && ev_loglevel_value == -1) {
-                       /*
-                        * Match is accepted. This is because on event creation, the
-                        * loglevel is set to -1 if the event loglevel type is ALL so 0 and
-                        * -1 are accepted for this loglevel type since 0 is the one set by
-                        * the API when receiving an enable event.
-                        */
-               } else {
-                       goto no_match;
-               }
+       if (!loglevels_match(event->attr.loglevel_type,
+                            event->attr.loglevel,
+                            key->loglevel_type,
+                            key->loglevel_value,
+                            LTTNG_UST_ABI_LOGLEVEL_ALL)) {
+               goto no_match;
        }
 
        /* One of the filters is NULL, fail. */
        }
 
        /* One of the filters is NULL, fail. */
@@ -264,7 +253,8 @@ static void add_unique_ust_app_event(struct ust_app_channel *ua_chan, struct ust
        ht = ua_chan->events;
        key.name = event->attr.name;
        key.filter = event->filter;
        ht = ua_chan->events;
        key.name = event->attr.name;
        key.filter = event->filter;
-       key.loglevel_type = (lttng_ust_abi_loglevel_type) event->attr.loglevel;
+       key.loglevel_type = (lttng_ust_abi_loglevel_type) event->attr.loglevel_type;
+       key.loglevel_value = event->attr.loglevel;
        key.exclusion = event->exclusion;
 
        node_ptr = cds_lfht_add_unique(ht->ht,
        key.exclusion = event->exclusion;
 
        node_ptr = cds_lfht_add_unique(ht->ht,
@@ -331,6 +321,12 @@ static void delete_ust_app_ctx(int sock, struct ust_app_ctx *ua_ctx, struct ust_
                }
                free(ua_ctx->obj);
        }
                }
                free(ua_ctx->obj);
        }
+
+       if (ua_ctx->ctx.ctx == LTTNG_UST_ABI_CONTEXT_APP_CONTEXT) {
+               free(ua_ctx->ctx.u.app_ctx.provider_name);
+               free(ua_ctx->ctx.u.app_ctx.ctx_name);
+       }
+
        free(ua_ctx);
 }
 
        free(ua_ctx);
 }
 
@@ -498,60 +494,62 @@ static void delete_ust_app_channel_rcu(struct rcu_head *head)
 static void save_per_pid_lost_discarded_counters(struct ust_app_channel *ua_chan)
 {
        uint64_t discarded = 0, lost = 0;
 static void save_per_pid_lost_discarded_counters(struct ust_app_channel *ua_chan)
 {
        uint64_t discarded = 0, lost = 0;
-       struct ltt_session *session;
        struct ltt_ust_channel *uchan;
 
        if (ua_chan->attr.type != LTTNG_UST_ABI_CHAN_PER_CPU) {
                return;
        }
 
        struct ltt_ust_channel *uchan;
 
        if (ua_chan->attr.type != LTTNG_UST_ABI_CHAN_PER_CPU) {
                return;
        }
 
-       rcu_read_lock();
-       session = session_find_by_id(ua_chan->session->tracing_id);
-       if (!session || !session->ust_session) {
-               /*
-                * Not finding the session is not an error because there are
-                * multiple ways the channels can be torn down.
-                *
-                * 1) The session daemon can initiate the destruction of the
-                *    ust app session after receiving a destroy command or
-                *    during its shutdown/teardown.
-                * 2) The application, since we are in per-pid tracing, is
-                *    unregistering and tearing down its ust app session.
-                *
-                * Both paths are protected by the session list lock which
-                * ensures that the accounting of lost packets and discarded
-                * events is done exactly once. The session is then unpublished
-                * from the session list, resulting in this condition.
-                */
-               goto end;
-       }
+       const lttng::urcu::read_lock_guard read_lock;
 
 
-       if (ua_chan->attr.overwrite) {
-               consumer_get_lost_packets(ua_chan->session->tracing_id,
-                                         ua_chan->key,
-                                         session->ust_session->consumer,
-                                         &lost);
-       } else {
-               consumer_get_discarded_events(ua_chan->session->tracing_id,
-                                             ua_chan->key,
-                                             session->ust_session->consumer,
-                                             &discarded);
-       }
-       uchan = trace_ust_find_channel_by_name(session->ust_session->domain_global.channels,
-                                              ua_chan->name);
-       if (!uchan) {
-               ERR("Missing UST channel to store discarded counters");
-               goto end;
+       try {
+               const auto session = ltt_session::find_session(ua_chan->session->tracing_id);
+
+               if (!session->ust_session) {
+                       /*
+                        * Not finding the session is not an error because there are
+                        * multiple ways the channels can be torn down.
+                        *
+                        * 1) The session daemon can initiate the destruction of the
+                        *    ust app session after receiving a destroy command or
+                        *    during its shutdown/teardown.
+                        * 2) The application, since we are in per-pid tracing, is
+                        *    unregistering and tearing down its ust app session.
+                        *
+                        * Both paths are protected by the session list lock which
+                        * ensures that the accounting of lost packets and discarded
+                        * events is done exactly once. The session is then unpublished
+                        * from the session list, resulting in this condition.
+                        */
+                       return;
+               }
+
+               if (ua_chan->attr.overwrite) {
+                       consumer_get_lost_packets(ua_chan->session->tracing_id,
+                                                 ua_chan->key,
+                                                 session->ust_session->consumer,
+                                                 &lost);
+               } else {
+                       consumer_get_discarded_events(ua_chan->session->tracing_id,
+                                                     ua_chan->key,
+                                                     session->ust_session->consumer,
+                                                     &discarded);
+               }
+               uchan = trace_ust_find_channel_by_name(session->ust_session->domain_global.channels,
+                                                      ua_chan->name);
+               if (!uchan) {
+                       ERR("Missing UST channel to store discarded counters");
+                       return;
+               }
+       } catch (const lttng::sessiond::exceptions::session_not_found_error& ex) {
+               DBG_FMT("Failed to save per-pid lost/discarded counters: {}, location='{}'",
+                       ex.what(),
+                       ex.source_location);
+               return;
        }
 
        uchan->per_pid_closed_app_discarded += discarded;
        uchan->per_pid_closed_app_lost += lost;
        }
 
        uchan->per_pid_closed_app_discarded += discarded;
        uchan->per_pid_closed_app_lost += lost;
-
-end:
-       rcu_read_unlock();
-       if (session) {
-               session_put(session);
-       }
 }
 
 /*
 }
 
 /*
@@ -563,13 +561,9 @@ end:
 static void delete_ust_app_channel(int sock,
                                   struct ust_app_channel *ua_chan,
                                   struct ust_app *app,
 static void delete_ust_app_channel(int sock,
                                   struct ust_app_channel *ua_chan,
                                   struct ust_app *app,
-                                  const lsu::registry_session::locked_ptr& locked_registry)
+                                  const lsu::registry_session::locked_ref& locked_registry)
 {
        int ret;
 {
        int ret;
-       struct lttng_ht_iter iter;
-       struct ust_app_event *ua_event;
-       struct ust_app_ctx *ua_ctx;
-       struct ust_app_stream *stream, *stmp;
 
        LTTNG_ASSERT(ua_chan);
        ASSERT_RCU_READ_LOCKED();
 
        LTTNG_ASSERT(ua_chan);
        ASSERT_RCU_READ_LOCKED();
@@ -577,22 +571,30 @@ static void delete_ust_app_channel(int sock,
        DBG3("UST app deleting channel %s", ua_chan->name);
 
        /* Wipe stream */
        DBG3("UST app deleting channel %s", ua_chan->name);
 
        /* Wipe stream */
-       cds_list_for_each_entry_safe (stream, stmp, &ua_chan->streams.head, list) {
+       for (auto *stream :
+            lttng::urcu::list_iteration_adapter<ust_app_stream, &ust_app_stream::list>(
+                    ua_chan->streams.head)) {
                cds_list_del(&stream->list);
                delete_ust_app_stream(sock, stream, app);
        }
 
        /* Wipe context */
                cds_list_del(&stream->list);
                delete_ust_app_stream(sock, stream, app);
        }
 
        /* Wipe context */
-       cds_lfht_for_each_entry (ua_chan->ctx->ht, &iter.iter, ua_ctx, node.node) {
+       for (auto ua_ctx :
+            lttng::urcu::lfht_iteration_adapter<ust_app_ctx,
+                                                decltype(ust_app_ctx::node),
+                                                &ust_app_ctx::node>(*ua_chan->ctx->ht)) {
                cds_list_del(&ua_ctx->list);
                cds_list_del(&ua_ctx->list);
-               ret = lttng_ht_del(ua_chan->ctx, &iter);
+               ret = cds_lfht_del(ua_chan->ctx->ht, &ua_ctx->node.node);
                LTTNG_ASSERT(!ret);
                delete_ust_app_ctx(sock, ua_ctx, app);
        }
 
        /* Wipe events */
                LTTNG_ASSERT(!ret);
                delete_ust_app_ctx(sock, ua_ctx, app);
        }
 
        /* Wipe events */
-       cds_lfht_for_each_entry (ua_chan->events->ht, &iter.iter, ua_event, node.node) {
-               ret = lttng_ht_del(ua_chan->events, &iter);
+       for (auto ua_event :
+            lttng::urcu::lfht_iteration_adapter<ust_app_event,
+                                                decltype(ust_app_event::node),
+                                                &ust_app_event::node>(*ua_chan->events->ht)) {
+               ret = cds_lfht_del(ua_chan->events->ht, &ua_event->node.node);
                LTTNG_ASSERT(!ret);
                delete_ust_app_event(sock, ua_event, app);
        }
                LTTNG_ASSERT(!ret);
                delete_ust_app_event(sock, ua_event, app);
        }
@@ -618,6 +620,8 @@ static void delete_ust_app_channel(int sock,
        }
 
        if (ua_chan->obj != nullptr) {
        }
 
        if (ua_chan->obj != nullptr) {
+               lttng_ht_iter iter;
+
                /* Remove channel from application UST object descriptor. */
                iter.iter.node = &ua_chan->ust_objd_node.node;
                ret = lttng_ht_del(app->ust_objd, &iter);
                /* Remove channel from application UST object descriptor. */
                iter.iter.node = &ua_chan->ust_objd_node.node;
                ret = lttng_ht_del(app->ust_objd, &iter);
@@ -689,7 +693,7 @@ int ust_app_release_object(struct ust_app *app, struct lttng_ust_abi_object_data
  * but it can be caused by recoverable errors (e.g. the application has
  * terminated concurrently).
  */
  * but it can be caused by recoverable errors (e.g. the application has
  * terminated concurrently).
  */
-ssize_t ust_app_push_metadata(const lsu::registry_session::locked_ptr& locked_registry,
+ssize_t ust_app_push_metadata(const lsu::registry_session::locked_ref& locked_registry,
                              struct consumer_socket *socket,
                              int send_zero_data)
 {
                              struct consumer_socket *socket,
                              int send_zero_data)
 {
@@ -828,7 +832,7 @@ error_push:
  * but it can be caused by recoverable errors (e.g. the application has
  * terminated concurrently).
  */
  * but it can be caused by recoverable errors (e.g. the application has
  * terminated concurrently).
  */
-static int push_metadata(const lsu::registry_session::locked_ptr& locked_registry,
+static int push_metadata(const lsu::registry_session::locked_ref& locked_registry,
                         struct consumer_output *consumer)
 {
        int ret_val;
                         struct consumer_output *consumer)
 {
        int ret_val;
@@ -880,7 +884,7 @@ static int close_metadata(uint64_t metadata_key,
 {
        int ret;
        struct consumer_socket *socket;
 {
        int ret;
        struct consumer_socket *socket;
-       lttng::urcu::read_lock_guard read_lock_guard;
+       const lttng::urcu::read_lock_guard read_lock_guard;
 
        LTTNG_ASSERT(consumer);
 
 
        LTTNG_ASSERT(consumer);
 
@@ -906,7 +910,7 @@ static void delete_ust_app_session_rcu(struct rcu_head *head)
                lttng::utils::container_of(head, &ust_app_session::rcu_head);
 
        lttng_ht_destroy(ua_sess->channels);
                lttng::utils::container_of(head, &ust_app_session::rcu_head);
 
        lttng_ht_destroy(ua_sess->channels);
-       free(ua_sess);
+       delete ua_sess;
 }
 
 /*
 }
 
 /*
@@ -917,28 +921,28 @@ static void delete_ust_app_session_rcu(struct rcu_head *head)
  */
 static void delete_ust_app_session(int sock, struct ust_app_session *ua_sess, struct ust_app *app)
 {
  */
 static void delete_ust_app_session(int sock, struct ust_app_session *ua_sess, struct ust_app *app)
 {
-       int ret;
-       struct lttng_ht_iter iter;
-       struct ust_app_channel *ua_chan;
-
        LTTNG_ASSERT(ua_sess);
        ASSERT_RCU_READ_LOCKED();
 
        LTTNG_ASSERT(ua_sess);
        ASSERT_RCU_READ_LOCKED();
 
-       pthread_mutex_lock(&ua_sess->lock);
+       /* Locked for the duration of the function. */
+       auto locked_ua_sess = ua_sess->lock();
 
        LTTNG_ASSERT(!ua_sess->deleted);
        ua_sess->deleted = true;
 
 
        LTTNG_ASSERT(!ua_sess->deleted);
        ua_sess->deleted = true;
 
-       auto locked_registry = get_locked_session_registry(ua_sess);
+       auto locked_registry = get_locked_session_registry(locked_ua_sess->get_identifier());
        /* Registry can be null on error path during initialization. */
        if (locked_registry) {
                /* Push metadata for application before freeing the application. */
                (void) push_metadata(locked_registry, ua_sess->consumer);
        }
 
        /* Registry can be null on error path during initialization. */
        if (locked_registry) {
                /* Push metadata for application before freeing the application. */
                (void) push_metadata(locked_registry, ua_sess->consumer);
        }
 
-       cds_lfht_for_each_entry (ua_sess->channels->ht, &iter.iter, ua_chan, node.node) {
-               ret = lttng_ht_del(ua_sess->channels, &iter);
-               LTTNG_ASSERT(!ret);
+       for (auto *ua_chan :
+            lttng::urcu::lfht_iteration_adapter<ust_app_channel,
+                                                decltype(ust_app_channel::node),
+                                                &ust_app_channel::node>(*ua_sess->channels->ht)) {
+               const auto ret = cds_lfht_del(ua_sess->channels->ht, &ua_chan->node.node);
+               LTTNG_ASSERT(ret == 0);
                delete_ust_app_channel(sock, ua_chan, app, locked_registry);
        }
 
                delete_ust_app_channel(sock, ua_chan, app, locked_registry);
        }
 
@@ -978,7 +982,7 @@ static void delete_ust_app_session(int sock, struct ust_app_session *ua_sess, st
 
        if (ua_sess->handle != -1) {
                pthread_mutex_lock(&app->sock_lock);
 
        if (ua_sess->handle != -1) {
                pthread_mutex_lock(&app->sock_lock);
-               ret = lttng_ust_ctl_release_handle(sock, ua_sess->handle);
+               auto ret = lttng_ust_ctl_release_handle(sock, ua_sess->handle);
                pthread_mutex_unlock(&app->sock_lock);
                if (ret < 0) {
                        if (ret == -EPIPE || ret == -LTTNG_UST_ERR_EXITING) {
                pthread_mutex_unlock(&app->sock_lock);
                if (ret < 0) {
                        if (ret == -EPIPE || ret == -LTTNG_UST_ERR_EXITING) {
@@ -998,15 +1002,11 @@ static void delete_ust_app_session(int sock, struct ust_app_session *ua_sess, st
                }
 
                /* Remove session from application UST object descriptor. */
                }
 
                /* Remove session from application UST object descriptor. */
-               iter.iter.node = &ua_sess->ust_objd_node.node;
-               ret = lttng_ht_del(app->ust_sessions_objd, &iter);
+               ret = cds_lfht_del(app->ust_sessions_objd->ht, &ua_sess->ust_objd_node.node);
                LTTNG_ASSERT(!ret);
        }
 
                LTTNG_ASSERT(!ret);
        }
 
-       pthread_mutex_unlock(&ua_sess->lock);
-
        consumer_output_put(ua_sess->consumer);
        consumer_output_put(ua_sess->consumer);
-
        call_rcu(&ua_sess->rcu_head, delete_ust_app_session_rcu);
 }
 
        call_rcu(&ua_sess->rcu_head, delete_ust_app_session_rcu);
 }
 
@@ -1017,42 +1017,44 @@ static void delete_ust_app_session(int sock, struct ust_app_session *ua_sess, st
 static void delete_ust_app(struct ust_app *app)
 {
        int ret, sock;
 static void delete_ust_app(struct ust_app *app)
 {
        int ret, sock;
-       struct ust_app_session *ua_sess, *tmp_ua_sess;
-       struct lttng_ht_iter iter;
-       struct ust_app_event_notifier_rule *event_notifier_rule;
        bool event_notifier_write_fd_is_open;
 
        /*
         * The session list lock must be held during this function to guarantee
         * the existence of ua_sess.
         */
        bool event_notifier_write_fd_is_open;
 
        /*
         * The session list lock must be held during this function to guarantee
         * the existence of ua_sess.
         */
-       session_lock_list();
+       const auto list_lock = lttng::sessiond::lock_session_list();
        /* Delete ust app sessions info */
        sock = app->sock;
        app->sock = -1;
 
        /* Wipe sessions */
        /* Delete ust app sessions info */
        sock = app->sock;
        app->sock = -1;
 
        /* Wipe sessions */
-       cds_list_for_each_entry_safe (ua_sess, tmp_ua_sess, &app->teardown_head, teardown_node) {
-               /* Free every object in the session and the session. */
-               rcu_read_lock();
-               delete_ust_app_session(sock, ua_sess, app);
-               rcu_read_unlock();
+       {
+               const lttng::urcu::read_lock_guard read_lock;
+
+               for (const auto ua_sess : app->sessions_to_teardown) {
+                       /* Free every object in the session and the session. */
+                       delete_ust_app_session(sock, ua_sess, app);
+               }
        }
 
        /* Remove the event notifier rules associated with this app. */
        }
 
        /* Remove the event notifier rules associated with this app. */
-       rcu_read_lock();
-       cds_lfht_for_each_entry (app->token_to_event_notifier_rule_ht->ht,
-                                &iter.iter,
-                                event_notifier_rule,
-                                node.node) {
-               ret = lttng_ht_del(app->token_to_event_notifier_rule_ht, &iter);
-               LTTNG_ASSERT(!ret);
+       {
+               const lttng::urcu::read_lock_guard read_lock;
+
+               for (auto *event_notifier_rule :
+                    lttng::urcu::lfht_iteration_adapter<ust_app_event_notifier_rule,
+                                                        decltype(ust_app_event_notifier_rule::node),
+                                                        &ust_app_event_notifier_rule::node>(
+                            *app->token_to_event_notifier_rule_ht->ht)) {
+                       ret = cds_lfht_del(app->token_to_event_notifier_rule_ht->ht,
+                                          &event_notifier_rule->node.node);
+                       LTTNG_ASSERT(!ret);
 
 
-               delete_ust_app_event_notifier_rule(app->sock, event_notifier_rule, app);
+                       delete_ust_app_event_notifier_rule(app->sock, event_notifier_rule, app);
+               }
        }
 
        }
 
-       rcu_read_unlock();
-
        lttng_ht_destroy(app->sessions);
        lttng_ht_destroy(app->ust_sessions_objd);
        lttng_ht_destroy(app->ust_objd);
        lttng_ht_destroy(app->sessions);
        lttng_ht_destroy(app->ust_sessions_objd);
        lttng_ht_destroy(app->ust_objd);
@@ -1115,8 +1117,7 @@ static void delete_ust_app(struct ust_app *app)
        lttng_fd_put(LTTNG_FD_APPS, 1);
 
        DBG2("UST app pid %d deleted", app->pid);
        lttng_fd_put(LTTNG_FD_APPS, 1);
 
        DBG2("UST app pid %d deleted", app->pid);
-       free(app);
-       session_unlock_list();
+       delete app;
 }
 
 /*
 }
 
 /*
@@ -1168,7 +1169,7 @@ static struct ust_app_session *alloc_ust_app_session()
        struct ust_app_session *ua_sess;
 
        /* Init most of the default value by allocating and zeroing */
        struct ust_app_session *ua_sess;
 
        /* Init most of the default value by allocating and zeroing */
-       ua_sess = zmalloc<ust_app_session>();
+       ua_sess = new ust_app_session;
        if (ua_sess == nullptr) {
                PERROR("malloc");
                goto error_free;
        if (ua_sess == nullptr) {
                PERROR("malloc");
                goto error_free;
@@ -1177,7 +1178,6 @@ static struct ust_app_session *alloc_ust_app_session()
        ua_sess->handle = -1;
        ua_sess->channels = lttng_ht_new(0, LTTNG_HT_TYPE_STRING);
        ua_sess->metadata_attr.type = LTTNG_UST_ABI_CHAN_METADATA;
        ua_sess->handle = -1;
        ua_sess->channels = lttng_ht_new(0, LTTNG_HT_TYPE_STRING);
        ua_sess->metadata_attr.type = LTTNG_UST_ABI_CHAN_METADATA;
-       pthread_mutex_init(&ua_sess->lock, nullptr);
 
        return ua_sess;
 
 
        return ua_sess;
 
@@ -1188,9 +1188,10 @@ error_free:
 /*
  * Alloc new UST app channel.
  */
 /*
  * Alloc new UST app channel.
  */
-static struct ust_app_channel *alloc_ust_app_channel(const char *name,
-                                                    struct ust_app_session *ua_sess,
-                                                    struct lttng_ust_abi_channel_attr *attr)
+static struct ust_app_channel *
+alloc_ust_app_channel(const char *name,
+                     const ust_app_session::locked_weak_ref& ua_sess,
+                     struct lttng_ust_abi_channel_attr *attr)
 {
        struct ust_app_channel *ua_chan;
 
 {
        struct ust_app_channel *ua_chan;
 
@@ -1205,9 +1206,9 @@ static struct ust_app_channel *alloc_ust_app_channel(const char *name,
        strncpy(ua_chan->name, name, sizeof(ua_chan->name));
        ua_chan->name[sizeof(ua_chan->name) - 1] = '\0';
 
        strncpy(ua_chan->name, name, sizeof(ua_chan->name));
        ua_chan->name[sizeof(ua_chan->name) - 1] = '\0';
 
-       ua_chan->enabled = 1;
+       ua_chan->enabled = true;
        ua_chan->handle = -1;
        ua_chan->handle = -1;
-       ua_chan->session = ua_sess;
+       ua_chan->session = &ua_sess.get();
        ua_chan->key = get_next_channel_key();
        ua_chan->ctx = lttng_ht_new(0, LTTNG_HT_TYPE_ULONG);
        ua_chan->events = lttng_ht_new(0, LTTNG_HT_TYPE_STRING);
        ua_chan->key = get_next_channel_key();
        ua_chan->ctx = lttng_ht_new(0, LTTNG_HT_TYPE_ULONG);
        ua_chan->events = lttng_ht_new(0, LTTNG_HT_TYPE_STRING);
@@ -1274,7 +1275,7 @@ static struct ust_app_event *alloc_ust_app_event(char *name, struct lttng_ust_ab
                goto error;
        }
 
                goto error;
        }
 
-       ua_event->enabled = 1;
+       ua_event->enabled = true;
        strncpy(ua_event->name, name, sizeof(ua_event->name));
        ua_event->name[sizeof(ua_event->name) - 1] = '\0';
        lttng_ht_node_init_str(&ua_event->node, ua_event->name);
        strncpy(ua_event->name, name, sizeof(ua_event->name));
        ua_event->name[sizeof(ua_event->name) - 1] = '\0';
        lttng_ht_node_init_str(&ua_event->node, ua_event->name);
@@ -1310,7 +1311,7 @@ alloc_ust_app_event_notifier_rule(struct lttng_trigger *trigger)
                goto error;
        }
 
                goto error;
        }
 
-       ua_event_notifier_rule->enabled = 1;
+       ua_event_notifier_rule->enabled = true;
        ua_event_notifier_rule->token = lttng_trigger_get_tracer_token(trigger);
        lttng_ht_node_init_u64(&ua_event_notifier_rule->node, ua_event_notifier_rule->token);
 
        ua_event_notifier_rule->token = lttng_trigger_get_tracer_token(trigger);
        lttng_ht_node_init_u64(&ua_event_notifier_rule->node, ua_event_notifier_rule->token);
 
@@ -1456,7 +1457,7 @@ struct ust_app *ust_app_find_by_sock(int sock)
        ASSERT_RCU_READ_LOCKED();
 
        lttng_ht_lookup(ust_app_ht_by_sock, (void *) ((unsigned long) sock), &iter);
        ASSERT_RCU_READ_LOCKED();
 
        lttng_ht_lookup(ust_app_ht_by_sock, (void *) ((unsigned long) sock), &iter);
-       node = lttng_ht_iter_get_node_ulong(&iter);
+       node = lttng_ht_iter_get_node<lttng_ht_node_ulong>(&iter);
        if (node == nullptr) {
                DBG2("UST app find by sock %d not found", sock);
                goto error;
        if (node == nullptr) {
                DBG2("UST app find by sock %d not found", sock);
                goto error;
@@ -1480,7 +1481,7 @@ static struct ust_app *find_app_by_notify_sock(int sock)
        ASSERT_RCU_READ_LOCKED();
 
        lttng_ht_lookup(ust_app_ht_by_notify_sock, (void *) ((unsigned long) sock), &iter);
        ASSERT_RCU_READ_LOCKED();
 
        lttng_ht_lookup(ust_app_ht_by_notify_sock, (void *) ((unsigned long) sock), &iter);
-       node = lttng_ht_iter_get_node_ulong(&iter);
+       node = lttng_ht_iter_get_node<lttng_ht_node_ulong>(&iter);
        if (node == nullptr) {
                DBG2("UST app find by notify sock %d not found", sock);
                goto error;
        if (node == nullptr) {
                DBG2("UST app find by notify sock %d not found", sock);
                goto error;
@@ -1501,6 +1502,7 @@ error:
 static struct ust_app_event *find_ust_app_event(struct lttng_ht *ht,
                                                const char *name,
                                                const struct lttng_bytecode *filter,
 static struct ust_app_event *find_ust_app_event(struct lttng_ht *ht,
                                                const char *name,
                                                const struct lttng_bytecode *filter,
+                                               lttng_ust_abi_loglevel_type loglevel_type,
                                                int loglevel_value,
                                                const struct lttng_event_exclusion *exclusion)
 {
                                                int loglevel_value,
                                                const struct lttng_event_exclusion *exclusion)
 {
@@ -1515,7 +1517,8 @@ static struct ust_app_event *find_ust_app_event(struct lttng_ht *ht,
        /* Setup key for event lookup. */
        key.name = name;
        key.filter = filter;
        /* Setup key for event lookup. */
        key.name = name;
        key.filter = filter;
-       key.loglevel_type = (lttng_ust_abi_loglevel_type) loglevel_value;
+       key.loglevel_type = loglevel_type;
+       key.loglevel_value = loglevel_value;
        /* lttng_event_exclusion and lttng_ust_event_exclusion structures are similar */
        key.exclusion = exclusion;
 
        /* lttng_event_exclusion and lttng_ust_event_exclusion structures are similar */
        key.exclusion = exclusion;
 
@@ -1525,7 +1528,7 @@ static struct ust_app_event *find_ust_app_event(struct lttng_ht *ht,
                        ht_match_ust_app_event,
                        &key,
                        &iter.iter);
                        ht_match_ust_app_event,
                        &key,
                        &iter.iter);
-       node = lttng_ht_iter_get_node_str(&iter);
+       node = lttng_ht_iter_get_node<lttng_ht_node_str>(&iter);
        if (node == nullptr) {
                goto end;
        }
        if (node == nullptr) {
                goto end;
        }
@@ -1553,7 +1556,7 @@ static struct ust_app_event_notifier_rule *find_ust_app_event_notifier_rule(stru
        ASSERT_RCU_READ_LOCKED();
 
        lttng_ht_lookup(ht, &token, &iter);
        ASSERT_RCU_READ_LOCKED();
 
        lttng_ht_lookup(ht, &token, &iter);
-       node = lttng_ht_iter_get_node_u64(&iter);
+       node = lttng_ht_iter_get_node<lttng_ht_node_u64>(&iter);
        if (node == nullptr) {
                DBG2("UST app event notifier rule token not found: token = %" PRIu64, token);
                goto end;
        if (node == nullptr) {
                DBG2("UST app event notifier rule token not found: token = %" PRIu64, token);
                goto end;
@@ -1722,7 +1725,7 @@ static struct lttng_ust_abi_event_exclusion *
 create_ust_exclusion_from_exclusion(const struct lttng_event_exclusion *exclusion)
 {
        struct lttng_ust_abi_event_exclusion *ust_exclusion = nullptr;
 create_ust_exclusion_from_exclusion(const struct lttng_event_exclusion *exclusion)
 {
        struct lttng_ust_abi_event_exclusion *ust_exclusion = nullptr;
-       size_t exclusion_alloc_size = sizeof(struct lttng_ust_abi_event_exclusion) +
+       const size_t exclusion_alloc_size = sizeof(struct lttng_ust_abi_event_exclusion) +
                LTTNG_UST_ABI_SYM_NAME_LEN * exclusion->count;
 
        ust_exclusion = zmalloc<lttng_ust_abi_event_exclusion>(exclusion_alloc_size);
                LTTNG_UST_ABI_SYM_NAME_LEN * exclusion->count;
 
        ust_exclusion = zmalloc<lttng_ust_abi_event_exclusion>(exclusion_alloc_size);
@@ -1833,7 +1836,7 @@ error:
  * Disable the specified channel on to UST tracer for the UST session.
  */
 static int disable_ust_channel(struct ust_app *app,
  * Disable the specified channel on to UST tracer for the UST session.
  */
 static int disable_ust_channel(struct ust_app *app,
-                              struct ust_app_session *ua_sess,
+                              const ust_app_session::locked_weak_ref& ua_sess,
                               struct ust_app_channel *ua_chan)
 {
        int ret;
                               struct ust_app_channel *ua_chan)
 {
        int ret;
@@ -1876,7 +1879,7 @@ error:
  * Enable the specified channel on to UST tracer for the UST session.
  */
 static int enable_ust_channel(struct ust_app *app,
  * Enable the specified channel on to UST tracer for the UST session.
  */
 static int enable_ust_channel(struct ust_app *app,
-                             struct ust_app_session *ua_sess,
+                             const ust_app_session::locked_weak_ref& ua_sess,
                              struct ust_app_channel *ua_chan)
 {
        int ret;
                              struct ust_app_channel *ua_chan)
 {
        int ret;
@@ -1910,7 +1913,7 @@ static int enable_ust_channel(struct ust_app *app,
                goto error;
        }
 
                goto error;
        }
 
-       ua_chan->enabled = 1;
+       ua_chan->enabled = true;
 
        DBG2("UST app channel %s enabled successfully for app: pid = %d", ua_chan->name, app->pid);
 
 
        DBG2("UST app channel %s enabled successfully for app: pid = %d", ua_chan->name, app->pid);
 
@@ -1969,7 +1972,6 @@ static int send_channel_pid_to_ust(struct ust_app *app,
                                   struct ust_app_channel *ua_chan)
 {
        int ret;
                                   struct ust_app_channel *ua_chan)
 {
        int ret;
-       struct ust_app_stream *stream, *stmp;
 
        LTTNG_ASSERT(app);
        LTTNG_ASSERT(ua_sess);
 
        LTTNG_ASSERT(app);
        LTTNG_ASSERT(ua_sess);
@@ -2001,7 +2003,9 @@ static int send_channel_pid_to_ust(struct ust_app *app,
        health_code_update();
 
        /* Send all streams to application. */
        health_code_update();
 
        /* Send all streams to application. */
-       cds_list_for_each_entry_safe (stream, stmp, &ua_chan->streams.head, list) {
+       for (auto *stream :
+            lttng::urcu::list_iteration_adapter<ust_app_stream, &ust_app_stream::list>(
+                    ua_chan->streams.head)) {
                ret = ust_consumer_send_stream_to_ust(app, ua_chan, stream);
                if (ret == -EPIPE || ret == -LTTNG_UST_ERR_EXITING) {
                        ret = -ENOTCONN; /* Caused by app exiting. */
                ret = ust_consumer_send_stream_to_ust(app, ua_chan, stream);
                if (ret == -EPIPE || ret == -LTTNG_UST_ERR_EXITING) {
                        ret = -ENOTCONN; /* Caused by app exiting. */
@@ -2236,6 +2240,7 @@ static int create_ust_event_notifier(struct ust_app *app,
        LTTNG_ASSERT(event_rule_type == LTTNG_EVENT_RULE_TYPE_USER_TRACEPOINT ||
                     event_rule_type == LTTNG_EVENT_RULE_TYPE_JUL_LOGGING ||
                     event_rule_type == LTTNG_EVENT_RULE_TYPE_LOG4J_LOGGING ||
        LTTNG_ASSERT(event_rule_type == LTTNG_EVENT_RULE_TYPE_USER_TRACEPOINT ||
                     event_rule_type == LTTNG_EVENT_RULE_TYPE_JUL_LOGGING ||
                     event_rule_type == LTTNG_EVENT_RULE_TYPE_LOG4J_LOGGING ||
+                    event_rule_type == LTTNG_EVENT_RULE_TYPE_LOG4J2_LOGGING ||
                     event_rule_type == LTTNG_EVENT_RULE_TYPE_PYTHON_LOGGING);
 
        init_ust_event_notifier_from_event_rule(event_rule, &event_notifier);
                     event_rule_type == LTTNG_EVENT_RULE_TYPE_PYTHON_LOGGING);
 
        init_ust_event_notifier_from_event_rule(event_rule, &event_notifier);
@@ -2519,9 +2524,8 @@ error:
 /*
  * Lookup sesison wrapper.
  */
 /*
  * Lookup sesison wrapper.
  */
-static void __lookup_session_by_app(const struct ltt_ust_session *usess,
-                                   struct ust_app *app,
-                                   struct lttng_ht_iter *iter)
+static void
+__lookup_session_by_app(const ltt_ust_session *usess, const ust_app *app, lttng_ht_iter *iter)
 {
        /* Get right UST app session from app */
        lttng_ht_lookup(app->sessions, &usess->id, iter);
 {
        /* Get right UST app session from app */
        lttng_ht_lookup(app->sessions, &usess->id, iter);
@@ -2531,14 +2535,14 @@ static void __lookup_session_by_app(const struct ltt_ust_session *usess,
  * Return ust app session from the app session hashtable using the UST session
  * id.
  */
  * Return ust app session from the app session hashtable using the UST session
  * id.
  */
-static struct ust_app_session *lookup_session_by_app(const struct ltt_ust_session *usess,
-                                                    struct ust_app *app)
+ust_app_session *ust_app_lookup_app_session(const struct ltt_ust_session *usess,
+                                           const struct ust_app *app)
 {
        struct lttng_ht_iter iter;
        struct lttng_ht_node_u64 *node;
 
        __lookup_session_by_app(usess, app, &iter);
 {
        struct lttng_ht_iter iter;
        struct lttng_ht_node_u64 *node;
 
        __lookup_session_by_app(usess, app, &iter);
-       node = lttng_ht_iter_get_node_u64(&iter);
+       node = lttng_ht_iter_get_node<lttng_ht_node_u64>(&iter);
        if (node == nullptr) {
                goto error;
        }
        if (node == nullptr) {
                goto error;
        }
@@ -2566,7 +2570,7 @@ static int setup_buffer_reg_pid(struct ust_app_session *ua_sess,
        LTTNG_ASSERT(ua_sess);
        LTTNG_ASSERT(app);
 
        LTTNG_ASSERT(ua_sess);
        LTTNG_ASSERT(app);
 
-       rcu_read_lock();
+       const lttng::urcu::read_lock_guard read_lock;
 
        reg_pid = buffer_reg_pid_find(ua_sess->id);
        if (!reg_pid) {
 
        reg_pid = buffer_reg_pid_find(ua_sess->id);
        if (!reg_pid) {
@@ -2614,7 +2618,6 @@ end:
                *regp = reg_pid;
        }
 error:
                *regp = reg_pid;
        }
 error:
-       rcu_read_unlock();
        return ret;
 }
 
        return ret;
 }
 
@@ -2636,7 +2639,7 @@ static int setup_buffer_reg_uid(struct ltt_ust_session *usess,
        LTTNG_ASSERT(usess);
        LTTNG_ASSERT(app);
 
        LTTNG_ASSERT(usess);
        LTTNG_ASSERT(app);
 
-       rcu_read_lock();
+       const lttng::urcu::read_lock_guard read_lock;
 
        reg_uid = buffer_reg_uid_find(usess->id, app->abi.bits_per_long, app->uid);
        if (!reg_uid) {
 
        reg_uid = buffer_reg_uid_find(usess->id, app->abi.bits_per_long, app->uid);
        if (!reg_uid) {
@@ -2690,7 +2693,6 @@ end:
                *regp = reg_uid;
        }
 error:
                *regp = reg_uid;
        }
 error:
-       rcu_read_unlock();
        return ret;
 }
 
        return ret;
 }
 
@@ -2719,7 +2721,7 @@ static int find_or_create_ust_app_session(struct ltt_ust_session *usess,
 
        health_code_update();
 
 
        health_code_update();
 
-       ua_sess = lookup_session_by_app(usess, app);
+       ua_sess = ust_app_lookup_app_session(usess, app);
        if (ua_sess == nullptr) {
                DBG2("UST app pid: %d session id %" PRIu64 " not found, creating it",
                     app->pid,
        if (ua_sess == nullptr) {
                DBG2("UST app pid: %d session id %" PRIu64 " not found, creating it",
                     app->pid,
@@ -2823,14 +2825,11 @@ error:
  */
 static int ht_match_ust_app_ctx(struct cds_lfht_node *node, const void *_key)
 {
  */
 static int ht_match_ust_app_ctx(struct cds_lfht_node *node, const void *_key)
 {
-       struct ust_app_ctx *ctx;
-       const struct lttng_ust_context_attr *key;
-
        LTTNG_ASSERT(node);
        LTTNG_ASSERT(_key);
 
        LTTNG_ASSERT(node);
        LTTNG_ASSERT(_key);
 
-       ctx = caa_container_of(node, struct ust_app_ctx, node.node);
-       key = (lttng_ust_context_attr *) _key;
+       auto *ctx = lttng_ht_node_container_of(node, &ust_app_ctx::node);
+       const auto *key = (lttng_ust_context_attr *) _key;
 
        /* Context type */
        if (ctx->ctx.ctx != key->ctx) {
 
        /* Context type */
        if (ctx->ctx.ctx != key->ctx) {
@@ -2885,7 +2884,7 @@ static struct ust_app_ctx *find_ust_app_context(struct lttng_ht *ht,
                        ht_match_ust_app_ctx,
                        uctx,
                        &iter.iter);
                        ht_match_ust_app_ctx,
                        uctx,
                        &iter.iter);
-       node = lttng_ht_iter_get_node_ulong(&iter);
+       node = lttng_ht_iter_get_node<lttng_ht_node_ulong>(&iter);
        if (!node) {
                goto end;
        }
        if (!node) {
                goto end;
        }
@@ -2952,7 +2951,7 @@ static int enable_ust_app_event(struct ust_app_event *ua_event, struct ust_app *
                goto error;
        }
 
                goto error;
        }
 
-       ua_event->enabled = 1;
+       ua_event->enabled = true;
 
 error:
        return ret;
 
 error:
        return ret;
@@ -2970,7 +2969,7 @@ static int disable_ust_app_event(struct ust_app_event *ua_event, struct ust_app
                goto error;
        }
 
                goto error;
        }
 
-       ua_event->enabled = 0;
+       ua_event->enabled = false;
 
 error:
        return ret;
 
 error:
        return ret;
@@ -2979,7 +2978,7 @@ error:
 /*
  * Lookup ust app channel for session and disable it on the tracer side.
  */
 /*
  * Lookup ust app channel for session and disable it on the tracer side.
  */
-static int disable_ust_app_channel(struct ust_app_session *ua_sess,
+static int disable_ust_app_channel(const ust_app_session::locked_weak_ref& ua_sess,
                                   struct ust_app_channel *ua_chan,
                                   struct ust_app *app)
 {
                                   struct ust_app_channel *ua_chan,
                                   struct ust_app *app)
 {
@@ -2990,7 +2989,7 @@ static int disable_ust_app_channel(struct ust_app_session *ua_sess,
                goto error;
        }
 
                goto error;
        }
 
-       ua_chan->enabled = 0;
+       ua_chan->enabled = false;
 
 error:
        return ret;
 
 error:
        return ret;
@@ -3000,7 +2999,7 @@ error:
  * Lookup ust app channel for session and enable it on the tracer side. This
  * MUST be called with a RCU read side lock acquired.
  */
  * Lookup ust app channel for session and enable it on the tracer side. This
  * MUST be called with a RCU read side lock acquired.
  */
-static int enable_ust_app_channel(struct ust_app_session *ua_sess,
+static int enable_ust_app_channel(const ust_app_session::locked_weak_ref& ua_sess,
                                  struct ltt_ust_channel *uchan,
                                  struct ust_app *app)
 {
                                  struct ltt_ust_channel *uchan,
                                  struct ust_app *app)
 {
@@ -3012,7 +3011,7 @@ static int enable_ust_app_channel(struct ust_app_session *ua_sess,
        ASSERT_RCU_READ_LOCKED();
 
        lttng_ht_lookup(ua_sess->channels, (void *) uchan->name, &iter);
        ASSERT_RCU_READ_LOCKED();
 
        lttng_ht_lookup(ua_sess->channels, (void *) uchan->name, &iter);
-       ua_chan_node = lttng_ht_iter_get_node_str(&iter);
+       ua_chan_node = lttng_ht_iter_get_node<lttng_ht_node_str>(&iter);
        if (ua_chan_node == nullptr) {
                DBG2("Unable to find channel %s in ust session id %" PRIu64,
                     uchan->name,
        if (ua_chan_node == nullptr) {
                DBG2("Unable to find channel %s in ust session id %" PRIu64,
                     uchan->name,
@@ -3053,7 +3052,7 @@ static int do_consumer_create_channel(struct ltt_ust_session *usess,
        LTTNG_ASSERT(ua_chan);
        LTTNG_ASSERT(registry);
 
        LTTNG_ASSERT(ua_chan);
        LTTNG_ASSERT(registry);
 
-       rcu_read_lock();
+       const lttng::urcu::read_lock_guard read_lock;
        health_code_update();
 
        /* Get the right consumer socket for the application. */
        health_code_update();
 
        /* Get the right consumer socket for the application. */
@@ -3108,7 +3107,6 @@ static int do_consumer_create_channel(struct ltt_ust_session *usess,
                }
        }
 
                }
        }
 
-       rcu_read_unlock();
        return 0;
 
 error_destroy:
        return 0;
 
 error_destroy:
@@ -3125,7 +3123,6 @@ error_ask:
        lttng_fd_put(LTTNG_FD_APPS, 1);
 error:
        health_code_update();
        lttng_fd_put(LTTNG_FD_APPS, 1);
 error:
        health_code_update();
-       rcu_read_unlock();
        return ret;
 }
 
        return ret;
 }
 
@@ -3217,7 +3214,6 @@ static int setup_buffer_reg_streams(struct buffer_reg_channel *buf_reg_chan,
                                    struct ust_app *app)
 {
        int ret = 0;
                                    struct ust_app *app)
 {
        int ret = 0;
-       struct ust_app_stream *stream, *stmp;
 
        LTTNG_ASSERT(buf_reg_chan);
        LTTNG_ASSERT(ua_chan);
 
        LTTNG_ASSERT(buf_reg_chan);
        LTTNG_ASSERT(ua_chan);
@@ -3225,7 +3221,9 @@ static int setup_buffer_reg_streams(struct buffer_reg_channel *buf_reg_chan,
        DBG2("UST app setup buffer registry stream");
 
        /* Send all streams to application. */
        DBG2("UST app setup buffer registry stream");
 
        /* Send all streams to application. */
-       cds_list_for_each_entry_safe (stream, stmp, &ua_chan->streams.head, list) {
+       for (auto *stream :
+            lttng::urcu::list_iteration_adapter<ust_app_stream, &ust_app_stream::list>(
+                    ua_chan->streams.head)) {
                struct buffer_reg_stream *reg_stream;
 
                ret = buffer_reg_stream_create(&reg_stream);
                struct buffer_reg_stream *reg_stream;
 
                ret = buffer_reg_stream_create(&reg_stream);
@@ -3353,7 +3351,6 @@ static int send_channel_uid_to_ust(struct buffer_reg_channel *buf_reg_chan,
                                   struct ust_app_channel *ua_chan)
 {
        int ret;
                                   struct ust_app_channel *ua_chan)
 {
        int ret;
-       struct buffer_reg_stream *reg_stream;
 
        LTTNG_ASSERT(buf_reg_chan);
        LTTNG_ASSERT(app);
 
        LTTNG_ASSERT(buf_reg_chan);
        LTTNG_ASSERT(app);
@@ -3390,7 +3387,9 @@ static int send_channel_uid_to_ust(struct buffer_reg_channel *buf_reg_chan,
 
        /* Send all streams to application. */
        pthread_mutex_lock(&buf_reg_chan->stream_list_lock);
 
        /* Send all streams to application. */
        pthread_mutex_lock(&buf_reg_chan->stream_list_lock);
-       cds_list_for_each_entry (reg_stream, &buf_reg_chan->streams, lnode) {
+       for (auto *reg_stream :
+            lttng::urcu::list_iteration_adapter<buffer_reg_stream, &buffer_reg_stream::lnode>(
+                    buf_reg_chan->streams)) {
                struct ust_app_stream stream = {};
 
                ret = duplicate_stream_object(reg_stream, &stream);
                struct ust_app_stream stream = {};
 
                ret = duplicate_stream_object(reg_stream, &stream);
@@ -3448,7 +3447,6 @@ static int create_channel_per_uid(struct ust_app *app,
        int ret;
        struct buffer_reg_uid *reg_uid;
        struct buffer_reg_channel *buf_reg_chan;
        int ret;
        struct buffer_reg_uid *reg_uid;
        struct buffer_reg_channel *buf_reg_chan;
-       struct ltt_session *session = nullptr;
        enum lttng_error_code notification_ret;
 
        LTTNG_ASSERT(app);
        enum lttng_error_code notification_ret;
 
        LTTNG_ASSERT(app);
@@ -3459,6 +3457,10 @@ static int create_channel_per_uid(struct ust_app *app,
 
        DBG("UST app creating channel %s with per UID buffers", ua_chan->name);
 
 
        DBG("UST app creating channel %s with per UID buffers", ua_chan->name);
 
+       /* Guaranteed to exist; will not throw. */
+       const auto session = ltt_session::find_session(ua_sess->tracing_id);
+       ASSERT_SESSION_LIST_LOCKED();
+
        reg_uid = buffer_reg_uid_find(usess->id, app->abi.bits_per_long, app->uid);
        /*
         * The session creation handles the creation of this global registry
        reg_uid = buffer_reg_uid_find(usess->id, app->abi.bits_per_long, app->uid);
        /*
         * The session creation handles the creation of this global registry
@@ -3479,11 +3481,6 @@ static int create_channel_per_uid(struct ust_app *app,
                goto error;
        }
 
                goto error;
        }
 
-       session = session_find_by_id(ua_sess->tracing_id);
-       LTTNG_ASSERT(session);
-       ASSERT_LOCKED(session->lock);
-       ASSERT_SESSION_LIST_LOCKED();
-
        /*
         * Create the buffers on the consumer side. This call populates the
         * ust app channel object with all streams and data object.
        /*
         * Create the buffers on the consumer side. This call populates the
         * ust app channel object with all streams and data object.
@@ -3549,9 +3546,6 @@ send_channel:
        }
 
 error:
        }
 
 error:
-       if (session) {
-               session_put(session);
-       }
        return ret;
 }
 
        return ret;
 }
 
@@ -3565,28 +3559,31 @@ error:
  */
 static int create_channel_per_pid(struct ust_app *app,
                                  struct ltt_ust_session *usess,
  */
 static int create_channel_per_pid(struct ust_app *app,
                                  struct ltt_ust_session *usess,
-                                 struct ust_app_session *ua_sess,
+                                 const ust_app_session::locked_weak_ref& ua_sess,
                                  struct ust_app_channel *ua_chan)
 {
        int ret;
        lsu::registry_session *registry;
        enum lttng_error_code cmd_ret;
                                  struct ust_app_channel *ua_chan)
 {
        int ret;
        lsu::registry_session *registry;
        enum lttng_error_code cmd_ret;
-       struct ltt_session *session = nullptr;
        uint64_t chan_reg_key;
 
        LTTNG_ASSERT(app);
        LTTNG_ASSERT(usess);
        uint64_t chan_reg_key;
 
        LTTNG_ASSERT(app);
        LTTNG_ASSERT(usess);
-       LTTNG_ASSERT(ua_sess);
        LTTNG_ASSERT(ua_chan);
 
        DBG("UST app creating channel %s with per PID buffers", ua_chan->name);
 
        LTTNG_ASSERT(ua_chan);
 
        DBG("UST app creating channel %s with per PID buffers", ua_chan->name);
 
-       rcu_read_lock();
+       const lttng::urcu::read_lock_guard read_lock;
 
 
-       registry = get_session_registry(ua_sess);
+       registry = ust_app_get_session_registry(ua_sess->get_identifier());
        /* The UST app session lock is held, registry shall not be null. */
        LTTNG_ASSERT(registry);
 
        /* The UST app session lock is held, registry shall not be null. */
        LTTNG_ASSERT(registry);
 
+       /* Guaranteed to exist; will not throw. */
+       const auto session = ltt_session::find_session(ua_sess->tracing_id);
+       ASSERT_LOCKED(session->_lock);
+       ASSERT_SESSION_LIST_LOCKED();
+
        /* Create and add a new channel registry to session. */
        try {
                registry->add_channel(ua_chan->key);
        /* Create and add a new channel registry to session. */
        try {
                registry->add_channel(ua_chan->key);
@@ -3598,19 +3595,15 @@ static int create_channel_per_pid(struct ust_app *app,
                goto error;
        }
 
                goto error;
        }
 
-       session = session_find_by_id(ua_sess->tracing_id);
-       LTTNG_ASSERT(session);
-       ASSERT_LOCKED(session->lock);
-       ASSERT_SESSION_LIST_LOCKED();
-
        /* Create and get channel on the consumer side. */
        /* Create and get channel on the consumer side. */
-       ret = do_consumer_create_channel(usess, ua_sess, ua_chan, app->abi.bits_per_long, registry);
+       ret = do_consumer_create_channel(
+               usess, &ua_sess.get(), ua_chan, app->abi.bits_per_long, registry);
        if (ret < 0) {
                ERR("Error creating UST channel \"%s\" on the consumer daemon", ua_chan->name);
                goto error_remove_from_registry;
        }
 
        if (ret < 0) {
                ERR("Error creating UST channel \"%s\" on the consumer daemon", ua_chan->name);
                goto error_remove_from_registry;
        }
 
-       ret = send_channel_pid_to_ust(app, ua_sess, ua_chan);
+       ret = send_channel_pid_to_ust(app, &ua_sess.get(), ua_chan);
        if (ret < 0) {
                if (ret != -ENOTCONN) {
                        ERR("Error sending channel to application");
        if (ret < 0) {
                if (ret != -ENOTCONN) {
                        ERR("Error sending channel to application");
@@ -3649,10 +3642,6 @@ error_remove_from_registry:
                }
        }
 error:
                }
        }
 error:
-       rcu_read_unlock();
-       if (session) {
-               session_put(session);
-       }
        return ret;
 }
 
        return ret;
 }
 
@@ -3668,7 +3657,7 @@ error:
  */
 static int ust_app_channel_send(struct ust_app *app,
                                struct ltt_ust_session *usess,
  */
 static int ust_app_channel_send(struct ust_app *app,
                                struct ltt_ust_session *usess,
-                               struct ust_app_session *ua_sess,
+                               const ust_app_session::locked_weak_ref& ua_sess,
                                struct ust_app_channel *ua_chan)
 {
        int ret;
                                struct ust_app_channel *ua_chan)
 {
        int ret;
@@ -3676,7 +3665,6 @@ static int ust_app_channel_send(struct ust_app *app,
        LTTNG_ASSERT(app);
        LTTNG_ASSERT(usess);
        LTTNG_ASSERT(usess->active);
        LTTNG_ASSERT(app);
        LTTNG_ASSERT(usess);
        LTTNG_ASSERT(usess->active);
-       LTTNG_ASSERT(ua_sess);
        LTTNG_ASSERT(ua_chan);
        ASSERT_RCU_READ_LOCKED();
 
        LTTNG_ASSERT(ua_chan);
        ASSERT_RCU_READ_LOCKED();
 
@@ -3684,7 +3672,7 @@ static int ust_app_channel_send(struct ust_app *app,
        switch (usess->buffer_type) {
        case LTTNG_BUFFER_PER_UID:
        {
        switch (usess->buffer_type) {
        case LTTNG_BUFFER_PER_UID:
        {
-               ret = create_channel_per_uid(app, usess, ua_sess, ua_chan);
+               ret = create_channel_per_uid(app, usess, &ua_sess.get(), ua_chan);
                if (ret < 0) {
                        goto error;
                }
                if (ret < 0) {
                        goto error;
                }
@@ -3727,7 +3715,7 @@ error:
  *
  * Return 0 on success or else a negative value.
  */
  *
  * Return 0 on success or else a negative value.
  */
-static int ust_app_channel_allocate(struct ust_app_session *ua_sess,
+static int ust_app_channel_allocate(const ust_app_session::locked_weak_ref& ua_sess,
                                    struct ltt_ust_channel *uchan,
                                    enum lttng_ust_abi_chan_type type,
                                    struct ltt_ust_session *usess __attribute__((unused)),
                                    struct ltt_ust_channel *uchan,
                                    enum lttng_ust_abi_chan_type type,
                                    struct ltt_ust_session *usess __attribute__((unused)),
@@ -3742,7 +3730,7 @@ static int ust_app_channel_allocate(struct ust_app_session *ua_sess,
 
        /* Lookup channel in the ust app session */
        lttng_ht_lookup(ua_sess->channels, (void *) uchan->name, &iter);
 
        /* Lookup channel in the ust app session */
        lttng_ht_lookup(ua_sess->channels, (void *) uchan->name, &iter);
-       ua_chan_node = lttng_ht_iter_get_node_str(&iter);
+       ua_chan_node = lttng_ht_iter_get_node<lttng_ht_node_str>(&iter);
        if (ua_chan_node != nullptr) {
                ua_chan = lttng::utils::container_of(ua_chan_node, &ust_app_channel::node);
                goto end;
        if (ua_chan_node != nullptr) {
                ua_chan = lttng::utils::container_of(ua_chan_node, &ust_app_channel::node);
                goto end;
@@ -3892,24 +3880,27 @@ end:
  *
  * Called with UST app session lock held and RCU read side lock.
  */
  *
  * Called with UST app session lock held and RCU read side lock.
  */
-static int create_ust_app_metadata(struct ust_app_session *ua_sess,
+static int create_ust_app_metadata(const ust_app_session::locked_weak_ref& ua_sess,
                                   struct ust_app *app,
                                   struct consumer_output *consumer)
 {
        int ret = 0;
        struct ust_app_channel *metadata;
        struct consumer_socket *socket;
                                   struct ust_app *app,
                                   struct consumer_output *consumer)
 {
        int ret = 0;
        struct ust_app_channel *metadata;
        struct consumer_socket *socket;
-       struct ltt_session *session = nullptr;
 
 
-       LTTNG_ASSERT(ua_sess);
        LTTNG_ASSERT(app);
        LTTNG_ASSERT(consumer);
        ASSERT_RCU_READ_LOCKED();
 
        LTTNG_ASSERT(app);
        LTTNG_ASSERT(consumer);
        ASSERT_RCU_READ_LOCKED();
 
-       auto locked_registry = get_locked_session_registry(ua_sess);
+       auto locked_registry = get_locked_session_registry(ua_sess->get_identifier());
        /* The UST app session is held registry shall not be null. */
        LTTNG_ASSERT(locked_registry);
 
        /* The UST app session is held registry shall not be null. */
        LTTNG_ASSERT(locked_registry);
 
+       /* Guaranteed to exist; will not throw. */
+       const auto session = ltt_session::find_session(ua_sess->tracing_id);
+       ASSERT_LOCKED(session->_lock);
+       ASSERT_SESSION_LIST_LOCKED();
+
        /* Metadata already exists for this registry or it was closed previously */
        if (locked_registry->_metadata_key || locked_registry->_metadata_closed) {
                ret = 0;
        /* Metadata already exists for this registry or it was closed previously */
        if (locked_registry->_metadata_key || locked_registry->_metadata_closed) {
                ret = 0;
@@ -3948,18 +3939,13 @@ static int create_ust_app_metadata(struct ust_app_session *ua_sess,
         */
        locked_registry->_metadata_key = metadata->key;
 
         */
        locked_registry->_metadata_key = metadata->key;
 
-       session = session_find_by_id(ua_sess->tracing_id);
-       LTTNG_ASSERT(session);
-       ASSERT_LOCKED(session->lock);
-       ASSERT_SESSION_LIST_LOCKED();
-
        /*
         * Ask the metadata channel creation to the consumer. The metadata object
         * will be created by the consumer and kept their. However, the stream is
         * never added or monitored until we do a first push metadata to the
         * consumer.
         */
        /*
         * Ask the metadata channel creation to the consumer. The metadata object
         * will be created by the consumer and kept their. However, the stream is
         * never added or monitored until we do a first push metadata to the
         * consumer.
         */
-       ret = ust_consumer_ask_channel(ua_sess,
+       ret = ust_consumer_ask_channel(&ua_sess.get(),
                                       metadata,
                                       consumer,
                                       socket,
                                       metadata,
                                       consumer,
                                       socket,
@@ -3990,9 +3976,6 @@ error_consumer:
        lttng_fd_put(LTTNG_FD_APPS, 1);
        delete_ust_app_channel(-1, metadata, app, locked_registry);
 error:
        lttng_fd_put(LTTNG_FD_APPS, 1);
        delete_ust_app_channel(-1, metadata, app, locked_registry);
 error:
-       if (session) {
-               session_put(session);
-       }
        return ret;
 }
 
        return ret;
 }
 
@@ -4007,7 +3990,7 @@ struct ust_app *ust_app_find_by_pid(pid_t pid)
        struct lttng_ht_iter iter;
 
        lttng_ht_lookup(ust_app_ht, (void *) ((unsigned long) pid), &iter);
        struct lttng_ht_iter iter;
 
        lttng_ht_lookup(ust_app_ht, (void *) ((unsigned long) pid), &iter);
-       node = lttng_ht_iter_get_node_ulong(&iter);
+       node = lttng_ht_iter_get_node<lttng_ht_node_ulong>(&iter);
        if (node == nullptr) {
                DBG2("UST app no found with pid %d", pid);
                goto error;
        if (node == nullptr) {
                DBG2("UST app no found with pid %d", pid);
                goto error;
@@ -4070,12 +4053,18 @@ struct ust_app *ust_app_create(struct ust_register_msg *msg, int sock)
                goto error;
        }
 
                goto error;
        }
 
-       lta = zmalloc<ust_app>();
-       if (lta == nullptr) {
-               PERROR("malloc");
+       try {
+               lta = new ust_app;
+       } catch (const std::bad_alloc&) {
+               ERR_FMT("Failed to allocate ust application instance: name=`{}`, pid={}, uid={}",
+                       msg->name,
+                       msg->pid,
+                       msg->uid);
                goto error_free_pipe;
        }
 
                goto error_free_pipe;
        }
 
+       urcu_ref_init(&lta->ref);
+
        lta->event_notifier_group.event_pipe = event_notifier_event_source_pipe;
 
        lta->ppid = msg->ppid;
        lta->event_notifier_group.event_pipe = event_notifier_event_source_pipe;
 
        lta->ppid = msg->ppid;
@@ -4119,7 +4108,6 @@ struct ust_app *ust_app_create(struct ust_register_msg *msg, int sock)
        pthread_mutex_init(&lta->sock_lock, nullptr);
        lttng_ht_node_init_ulong(&lta->sock_n, (unsigned long) lta->sock);
 
        pthread_mutex_init(&lta->sock_lock, nullptr);
        lttng_ht_node_init_ulong(&lta->sock_n, (unsigned long) lta->sock);
 
-       CDS_INIT_LIST_HEAD(&lta->teardown_head);
        return lta;
 
 error_free_pipe:
        return lta;
 
 error_free_pipe:
@@ -4139,7 +4127,7 @@ void ust_app_add(struct ust_app *app)
 
        app->registration_time = time(nullptr);
 
 
        app->registration_time = time(nullptr);
 
-       rcu_read_lock();
+       const lttng::urcu::read_lock_guard read_lock;
 
        /*
         * On a re-registration, we want to kick out the previous registration of
 
        /*
         * On a re-registration, we want to kick out the previous registration of
@@ -4169,8 +4157,6 @@ void ust_app_add(struct ust_app *app)
            app->notify_sock,
            app->v_major,
            app->v_minor);
            app->notify_sock,
            app->v_major,
            app->v_minor);
-
-       rcu_read_unlock();
 }
 
 /*
 }
 
 /*
@@ -4335,30 +4321,9 @@ error:
        return ret;
 }
 
        return ret;
 }
 
-/*
- * Unregister app by removing it from the global traceable app list and freeing
- * the data struct.
- *
- * The socket is already closed at this point so no close to sock.
- */
-void ust_app_unregister(int sock)
+static void ust_app_unregister(ust_app& app)
 {
 {
-       struct ust_app *lta;
-       struct lttng_ht_node_ulong *node;
-       struct lttng_ht_iter ust_app_sock_iter;
-       struct lttng_ht_iter iter;
-       struct ust_app_session *ua_sess;
-       int ret;
-
-       rcu_read_lock();
-
-       /* Get the node reference for a call_rcu */
-       lttng_ht_lookup(ust_app_ht_by_sock, (void *) ((unsigned long) sock), &ust_app_sock_iter);
-       node = lttng_ht_iter_get_node_ulong(&ust_app_sock_iter);
-       LTTNG_ASSERT(node);
-
-       lta = lttng::utils::container_of(node, &ust_app::sock_n);
-       DBG("PID %d unregistering with sock %d", lta->pid, sock);
+       const lttng::urcu::read_lock_guard read_lock;
 
        /*
         * For per-PID buffers, perform "push metadata" and flush all
 
        /*
         * For per-PID buffers, perform "push metadata" and flush all
@@ -4366,25 +4331,27 @@ void ust_app_unregister(int sock)
         * ensuring proper behavior of data_pending check.
         * Remove sessions so they are not visible during deletion.
         */
         * ensuring proper behavior of data_pending check.
         * Remove sessions so they are not visible during deletion.
         */
-       cds_lfht_for_each_entry (lta->sessions->ht, &iter.iter, ua_sess, node.node) {
-               ret = lttng_ht_del(lta->sessions, &iter);
-               if (ret) {
+       for (auto *ua_sess :
+            lttng::urcu::lfht_iteration_adapter<ust_app_session,
+                                                decltype(ust_app_session::node),
+                                                &ust_app_session::node>(*app.sessions->ht)) {
+               const auto del_ret = cds_lfht_del(app.sessions->ht, &ua_sess->node.node);
+               if (del_ret) {
                        /* The session was already removed so scheduled for teardown. */
                        continue;
                }
 
                if (ua_sess->buffer_type == LTTNG_BUFFER_PER_PID) {
                        /* The session was already removed so scheduled for teardown. */
                        continue;
                }
 
                if (ua_sess->buffer_type == LTTNG_BUFFER_PER_PID) {
-                       (void) ust_app_flush_app_session(lta, ua_sess);
+                       (void) ust_app_flush_app_session(app, *ua_sess);
                }
 
                /*
                 * Add session to list for teardown. This is safe since at this point we
                 * are the only one using this list.
                 */
                }
 
                /*
                 * Add session to list for teardown. This is safe since at this point we
                 * are the only one using this list.
                 */
-               pthread_mutex_lock(&ua_sess->lock);
+               auto locked_ua_sess = ua_sess->lock();
 
                if (ua_sess->deleted) {
 
                if (ua_sess->deleted) {
-                       pthread_mutex_unlock(&ua_sess->lock);
                        continue;
                }
 
                        continue;
                }
 
@@ -4399,7 +4366,8 @@ void ust_app_unregister(int sock)
                 * The close metadata below nullifies the metadata pointer in the
                 * session so the delete session will NOT push/close a second time.
                 */
                 * The close metadata below nullifies the metadata pointer in the
                 * session so the delete session will NOT push/close a second time.
                 */
-               auto locked_registry = get_locked_session_registry(ua_sess);
+               auto locked_registry =
+                       get_locked_session_registry(locked_ua_sess->get_identifier());
                if (locked_registry) {
                        /* Push metadata for application before freeing the application. */
                        (void) push_metadata(locked_registry, ua_sess->consumer);
                if (locked_registry) {
                        /* Push metadata for application before freeing the application. */
                        (void) push_metadata(locked_registry, ua_sess->consumer);
@@ -4427,40 +4395,62 @@ void ust_app_unregister(int sock)
                                locked_registry.reset();
                        }
                }
                                locked_registry.reset();
                        }
                }
-               cds_list_add(&ua_sess->teardown_node, &lta->teardown_head);
 
 
-               pthread_mutex_unlock(&ua_sess->lock);
+               app.sessions_to_teardown.emplace_back(ua_sess);
        }
 
        }
 
-       /* Remove application from PID hash table */
-       ret = lttng_ht_del(ust_app_ht_by_sock, &ust_app_sock_iter);
-       LTTNG_ASSERT(!ret);
-
        /*
         * Remove application from notify hash table. The thread handling the
         * notify socket could have deleted the node so ignore on error because
         * either way it's valid. The close of that socket is handled by the
         * apps_notify_thread.
         */
        /*
         * Remove application from notify hash table. The thread handling the
         * notify socket could have deleted the node so ignore on error because
         * either way it's valid. The close of that socket is handled by the
         * apps_notify_thread.
         */
-       iter.iter.node = &lta->notify_sock_n.node;
-       (void) lttng_ht_del(ust_app_ht_by_notify_sock, &iter);
+       (void) cds_lfht_del(ust_app_ht_by_notify_sock->ht, &app.notify_sock_n.node);
 
        /*
         * Ignore return value since the node might have been removed before by an
         * add replace during app registration because the PID can be reassigned by
         * the OS.
         */
 
        /*
         * Ignore return value since the node might have been removed before by an
         * add replace during app registration because the PID can be reassigned by
         * the OS.
         */
-       iter.iter.node = &lta->pid_n.node;
-       ret = lttng_ht_del(ust_app_ht, &iter);
-       if (ret) {
-               DBG3("Unregister app by PID %d failed. This can happen on pid reuse", lta->pid);
+       if (cds_lfht_del(ust_app_ht->ht, &app.pid_n.node)) {
+               DBG3("Unregister app by PID %d failed. This can happen on pid reuse", app.pid);
        }
        }
+}
+
+/*
+ * Unregister app by removing it from the global traceable app list and freeing
+ * the data struct.
+ *
+ * The socket is already closed at this point, so there is no need to close it.
+ */
+void ust_app_unregister_by_socket(int sock_fd)
+{
+       struct lttng_ht_node_ulong *node;
+       struct lttng_ht_iter ust_app_sock_iter;
+       int ret;
 
 
-       /* Free memory */
-       call_rcu(&lta->pid_n.head, delete_ust_app_rcu);
+       const lttng::urcu::read_lock_guard read_lock;
 
 
-       rcu_read_unlock();
-       return;
+       /* Get the node reference for a call_rcu */
+       lttng_ht_lookup(ust_app_ht_by_sock, (void *) ((unsigned long) sock_fd), &ust_app_sock_iter);
+       node = lttng_ht_iter_get_node<lttng_ht_node_ulong>(&ust_app_sock_iter);
+       assert(node);
+
+       auto *app = lttng::utils::container_of(node, &ust_app::sock_n);
+
+       DBG_FMT("Application unregistering after socket activity: app={}, socket_fd={}",
+               *app,
+               sock_fd);
+
+       /* Remove application from socket hash table */
+       ret = lttng_ht_del(ust_app_ht_by_sock, &ust_app_sock_iter);
+       assert(!ret);
+
+       /*
+        * The socket is closed: release its reference to the application
+        * to trigger its eventual teardown.
+        */
+       ust_app_put(app);
 }
 
 /*
 }
 
 /*
@@ -4470,8 +4460,6 @@ int ust_app_list_events(struct lttng_event **events)
 {
        int ret, handle;
        size_t nbmem, count = 0;
 {
        int ret, handle;
        size_t nbmem, count = 0;
-       struct lttng_ht_iter iter;
-       struct ust_app *app;
        struct lttng_event *tmp_event;
 
        nbmem = UST_APP_EVENT_LIST_SIZE;
        struct lttng_event *tmp_event;
 
        nbmem = UST_APP_EVENT_LIST_SIZE;
@@ -4482,9 +4470,10 @@ int ust_app_list_events(struct lttng_event **events)
                goto error;
        }
 
                goto error;
        }
 
-       rcu_read_lock();
-
-       cds_lfht_for_each_entry (ust_app_ht->ht, &iter.iter, app, pid_n.node) {
+       /* Iterate on all apps. */
+       for (auto *app :
+            lttng::urcu::lfht_iteration_adapter<ust_app, decltype(ust_app::pid_n), &ust_app::pid_n>(
+                    *ust_app_ht->ht)) {
                struct lttng_ust_abi_tracepoint_iter uiter;
 
                health_code_update();
                struct lttng_ust_abi_tracepoint_iter uiter;
 
                health_code_update();
@@ -4496,6 +4485,7 @@ int ust_app_list_events(struct lttng_event **events)
                         */
                        continue;
                }
                         */
                        continue;
                }
+
                pthread_mutex_lock(&app->sock_lock);
                handle = lttng_ust_ctl_tracepoint_list(app->sock);
                if (handle < 0) {
                pthread_mutex_lock(&app->sock_lock);
                handle = lttng_ust_ctl_tracepoint_list(app->sock);
                if (handle < 0) {
@@ -4521,6 +4511,7 @@ int ust_app_list_events(struct lttng_event **events)
                                        DBG3("UST app tp list get failed. Application is dead");
                                        break;
                                }
                                        DBG3("UST app tp list get failed. Application is dead");
                                        break;
                                }
+
                                free(tmp_event);
                                release_ret = lttng_ust_ctl_release_handle(app->sock, handle);
                                if (release_ret < 0 && release_ret != -LTTNG_UST_ERR_EXITING &&
                                free(tmp_event);
                                release_ret = lttng_ust_ctl_release_handle(app->sock, handle);
                                if (release_ret < 0 && release_ret != -LTTNG_UST_ERR_EXITING &&
@@ -4529,6 +4520,7 @@ int ust_app_list_events(struct lttng_event **events)
                                            app->sock,
                                            release_ret);
                                }
                                            app->sock,
                                            release_ret);
                                }
+
                                pthread_mutex_unlock(&app->sock_lock);
                                goto rcu_error;
                        }
                                pthread_mutex_unlock(&app->sock_lock);
                                goto rcu_error;
                        }
@@ -4560,6 +4552,7 @@ int ust_app_list_events(struct lttng_event **events)
                                                    app->sock,
                                                    release_ret);
                                        }
                                                    app->sock,
                                                    release_ret);
                                        }
+
                                        pthread_mutex_unlock(&app->sock_lock);
                                        goto rcu_error;
                                }
                                        pthread_mutex_unlock(&app->sock_lock);
                                        goto rcu_error;
                                }
@@ -4570,6 +4563,7 @@ int ust_app_list_events(struct lttng_event **events)
                                nbmem = new_nbmem;
                                tmp_event = new_tmp_event;
                        }
                                nbmem = new_nbmem;
                                tmp_event = new_tmp_event;
                        }
+
                        memcpy(tmp_event[count].name, uiter.name, LTTNG_UST_ABI_SYM_NAME_LEN);
                        tmp_event[count].loglevel = uiter.loglevel;
                        tmp_event[count].type = (enum lttng_event_type) LTTNG_UST_ABI_TRACEPOINT;
                        memcpy(tmp_event[count].name, uiter.name, LTTNG_UST_ABI_SYM_NAME_LEN);
                        tmp_event[count].loglevel = uiter.loglevel;
                        tmp_event[count].type = (enum lttng_event_type) LTTNG_UST_ABI_TRACEPOINT;
@@ -4577,6 +4571,7 @@ int ust_app_list_events(struct lttng_event **events)
                        tmp_event[count].enabled = -1;
                        count++;
                }
                        tmp_event[count].enabled = -1;
                        count++;
                }
+
                ret = lttng_ust_ctl_release_handle(app->sock, handle);
                pthread_mutex_unlock(&app->sock_lock);
                if (ret < 0) {
                ret = lttng_ust_ctl_release_handle(app->sock, handle);
                pthread_mutex_unlock(&app->sock_lock);
                if (ret < 0) {
@@ -4603,7 +4598,6 @@ int ust_app_list_events(struct lttng_event **events)
        DBG2("UST app list events done (%zu events)", count);
 
 rcu_error:
        DBG2("UST app list events done (%zu events)", count);
 
 rcu_error:
-       rcu_read_unlock();
 error:
        health_code_update();
        return ret;
 error:
        health_code_update();
        return ret;
@@ -4616,8 +4610,6 @@ int ust_app_list_event_fields(struct lttng_event_field **fields)
 {
        int ret, handle;
        size_t nbmem, count = 0;
 {
        int ret, handle;
        size_t nbmem, count = 0;
-       struct lttng_ht_iter iter;
-       struct ust_app *app;
        struct lttng_event_field *tmp_event;
 
        nbmem = UST_APP_EVENT_LIST_SIZE;
        struct lttng_event_field *tmp_event;
 
        nbmem = UST_APP_EVENT_LIST_SIZE;
@@ -4628,9 +4620,10 @@ int ust_app_list_event_fields(struct lttng_event_field **fields)
                goto error;
        }
 
                goto error;
        }
 
-       rcu_read_lock();
-
-       cds_lfht_for_each_entry (ust_app_ht->ht, &iter.iter, app, pid_n.node) {
+       /* Iterate on all apps. */
+       for (auto *app :
+            lttng::urcu::lfht_iteration_adapter<ust_app, decltype(ust_app::pid_n), &ust_app::pid_n>(
+                    *ust_app_ht->ht)) {
                struct lttng_ust_abi_field_iter uiter;
 
                health_code_update();
                struct lttng_ust_abi_field_iter uiter;
 
                health_code_update();
@@ -4642,6 +4635,7 @@ int ust_app_list_event_fields(struct lttng_event_field **fields)
                         */
                        continue;
                }
                         */
                        continue;
                }
+
                pthread_mutex_lock(&app->sock_lock);
                handle = lttng_ust_ctl_tracepoint_field_list(app->sock);
                if (handle < 0) {
                pthread_mutex_lock(&app->sock_lock);
                handle = lttng_ust_ctl_tracepoint_field_list(app->sock);
                if (handle < 0) {
@@ -4667,6 +4661,7 @@ int ust_app_list_event_fields(struct lttng_event_field **fields)
                                        DBG3("UST app tp list field failed. Application is dead");
                                        break;
                                }
                                        DBG3("UST app tp list field failed. Application is dead");
                                        break;
                                }
+
                                free(tmp_event);
                                release_ret = lttng_ust_ctl_release_handle(app->sock, handle);
                                pthread_mutex_unlock(&app->sock_lock);
                                free(tmp_event);
                                release_ret = lttng_ust_ctl_release_handle(app->sock, handle);
                                pthread_mutex_unlock(&app->sock_lock);
@@ -4676,6 +4671,7 @@ int ust_app_list_event_fields(struct lttng_event_field **fields)
                                            app->sock,
                                            release_ret);
                                }
                                            app->sock,
                                            release_ret);
                                }
+
                                goto rcu_error;
                        }
 
                                goto rcu_error;
                        }
 
@@ -4706,8 +4702,10 @@ int ust_app_list_event_fields(struct lttng_event_field **fields)
                                                    app->sock,
                                                    release_ret);
                                        }
                                                    app->sock,
                                                    release_ret);
                                        }
+
                                        goto rcu_error;
                                }
                                        goto rcu_error;
                                }
+
                                /* Zero the new memory */
                                memset(new_tmp_event + nbmem,
                                       0,
                                /* Zero the new memory */
                                memset(new_tmp_event + nbmem,
                                       0,
@@ -4732,6 +4730,7 @@ int ust_app_list_event_fields(struct lttng_event_field **fields)
                        tmp_event[count].event.enabled = -1;
                        count++;
                }
                        tmp_event[count].event.enabled = -1;
                        count++;
                }
+
                ret = lttng_ust_ctl_release_handle(app->sock, handle);
                pthread_mutex_unlock(&app->sock_lock);
                if (ret < 0 && ret != -LTTNG_UST_ERR_EXITING && ret != -EPIPE) {
                ret = lttng_ust_ctl_release_handle(app->sock, handle);
                pthread_mutex_unlock(&app->sock_lock);
                if (ret < 0 && ret != -LTTNG_UST_ERR_EXITING && ret != -EPIPE) {
@@ -4745,7 +4744,6 @@ int ust_app_list_event_fields(struct lttng_event_field **fields)
        DBG2("UST app list event fields done (%zu events)", count);
 
 rcu_error:
        DBG2("UST app list event fields done (%zu events)", count);
 
 rcu_error:
-       rcu_read_unlock();
 error:
        health_code_update();
        return ret;
 error:
        health_code_update();
        return ret;
@@ -4757,45 +4755,38 @@ error:
 void ust_app_clean_list()
 {
        int ret;
 void ust_app_clean_list()
 {
        int ret;
-       struct ust_app *app;
-       struct lttng_ht_iter iter;
-
        DBG2("UST app cleaning registered apps hash table");
 
        DBG2("UST app cleaning registered apps hash table");
 
-       rcu_read_lock();
-
        /* Cleanup notify socket hash table */
        if (ust_app_ht_by_notify_sock) {
        /* Cleanup notify socket hash table */
        if (ust_app_ht_by_notify_sock) {
-               cds_lfht_for_each_entry (
-                       ust_app_ht_by_notify_sock->ht, &iter.iter, app, notify_sock_n.node) {
+               for (auto *app :
+                    lttng::urcu::lfht_iteration_adapter<ust_app,
+                                                        decltype(ust_app::notify_sock_n),
+                                                        &ust_app::notify_sock_n>(
+                            *ust_app_ht_by_notify_sock->ht)) {
                        /*
                         * Assert that all notifiers are gone as all triggers
                         * are unregistered prior to this clean-up.
                         */
                        LTTNG_ASSERT(lttng_ht_get_count(app->token_to_event_notifier_rule_ht) == 0);
                        /*
                         * Assert that all notifiers are gone as all triggers
                         * are unregistered prior to this clean-up.
                         */
                        LTTNG_ASSERT(lttng_ht_get_count(app->token_to_event_notifier_rule_ht) == 0);
-
                        ust_app_notify_sock_unregister(app->notify_sock);
                }
        }
 
                        ust_app_notify_sock_unregister(app->notify_sock);
                }
        }
 
-       if (ust_app_ht) {
-               cds_lfht_for_each_entry (ust_app_ht->ht, &iter.iter, app, pid_n.node) {
-                       ret = lttng_ht_del(ust_app_ht, &iter);
-                       LTTNG_ASSERT(!ret);
-                       call_rcu(&app->pid_n.head, delete_ust_app_rcu);
-               }
-       }
-
        /* Cleanup socket hash table */
        if (ust_app_ht_by_sock) {
        /* Cleanup socket hash table */
        if (ust_app_ht_by_sock) {
-               cds_lfht_for_each_entry (ust_app_ht_by_sock->ht, &iter.iter, app, sock_n.node) {
-                       ret = lttng_ht_del(ust_app_ht_by_sock, &iter);
+               const lttng::urcu::read_lock_guard read_lock;
+
+               for (auto *app : lttng::urcu::lfht_iteration_adapter<ust_app,
+                                                                    decltype(ust_app::sock_n),
+                                                                    &ust_app::sock_n>(
+                            *ust_app_ht_by_sock->ht)) {
+                       ret = cds_lfht_del(ust_app_ht_by_sock->ht, &app->sock_n.node);
                        LTTNG_ASSERT(!ret);
                        LTTNG_ASSERT(!ret);
+                       ust_app_put(app);
                }
        }
 
                }
        }
 
-       rcu_read_unlock();
-
        /* Destroy is done only when the ht is empty */
        if (ust_app_ht) {
                lttng_ht_destroy(ust_app_ht);
        /* Destroy is done only when the ht is empty */
        if (ust_app_ht) {
                lttng_ht_destroy(ust_app_ht);
@@ -4834,9 +4825,7 @@ int ust_app_ht_alloc()
 int ust_app_disable_channel_glb(struct ltt_ust_session *usess, struct ltt_ust_channel *uchan)
 {
        int ret = 0;
 int ust_app_disable_channel_glb(struct ltt_ust_session *usess, struct ltt_ust_channel *uchan)
 {
        int ret = 0;
-       struct lttng_ht_iter iter;
        struct lttng_ht_node_str *ua_chan_node;
        struct lttng_ht_node_str *ua_chan_node;
-       struct ust_app *app;
        struct ust_app_session *ua_sess;
        struct ust_app_channel *ua_chan;
 
        struct ust_app_session *ua_sess;
        struct ust_app_channel *ua_chan;
 
@@ -4845,10 +4834,10 @@ int ust_app_disable_channel_glb(struct ltt_ust_session *usess, struct ltt_ust_ch
             uchan->name,
             usess->id);
 
             uchan->name,
             usess->id);
 
-       rcu_read_lock();
-
-       /* For every registered applications */
-       cds_lfht_for_each_entry (ust_app_ht->ht, &iter.iter, app, pid_n.node) {
+       /* Iterate on all apps. */
+       for (auto *app :
+            lttng::urcu::lfht_iteration_adapter<ust_app, decltype(ust_app::pid_n), &ust_app::pid_n>(
+                    *ust_app_ht->ht)) {
                struct lttng_ht_iter uiter;
                if (!app->compatible) {
                        /*
                struct lttng_ht_iter uiter;
                if (!app->compatible) {
                        /*
@@ -4857,30 +4846,29 @@ int ust_app_disable_channel_glb(struct ltt_ust_session *usess, struct ltt_ust_ch
                         */
                        continue;
                }
                         */
                        continue;
                }
-               ua_sess = lookup_session_by_app(usess, app);
+               ua_sess = ust_app_lookup_app_session(usess, app);
                if (ua_sess == nullptr) {
                        continue;
                }
 
                /* Get channel */
                lttng_ht_lookup(ua_sess->channels, (void *) uchan->name, &uiter);
                if (ua_sess == nullptr) {
                        continue;
                }
 
                /* Get channel */
                lttng_ht_lookup(ua_sess->channels, (void *) uchan->name, &uiter);
-               ua_chan_node = lttng_ht_iter_get_node_str(&uiter);
+               ua_chan_node = lttng_ht_iter_get_node<lttng_ht_node_str>(&uiter);
                /* If the session if found for the app, the channel must be there */
                LTTNG_ASSERT(ua_chan_node);
 
                ua_chan = lttng::utils::container_of(ua_chan_node, &ust_app_channel::node);
                /* The channel must not be already disabled */
                /* If the session if found for the app, the channel must be there */
                LTTNG_ASSERT(ua_chan_node);
 
                ua_chan = lttng::utils::container_of(ua_chan_node, &ust_app_channel::node);
                /* The channel must not be already disabled */
-               LTTNG_ASSERT(ua_chan->enabled == 1);
+               LTTNG_ASSERT(ua_chan->enabled);
 
                /* Disable channel onto application */
 
                /* Disable channel onto application */
-               ret = disable_ust_app_channel(ua_sess, ua_chan, app);
+               ret = disable_ust_app_channel(ua_sess->lock(), ua_chan, app);
                if (ret < 0) {
                        /* XXX: We might want to report this error at some point... */
                        continue;
                }
        }
 
                if (ret < 0) {
                        /* XXX: We might want to report this error at some point... */
                        continue;
                }
        }
 
-       rcu_read_unlock();
        return ret;
 }
 
        return ret;
 }
 
@@ -4890,8 +4878,6 @@ int ust_app_disable_channel_glb(struct ltt_ust_session *usess, struct ltt_ust_ch
 int ust_app_enable_channel_glb(struct ltt_ust_session *usess, struct ltt_ust_channel *uchan)
 {
        int ret = 0;
 int ust_app_enable_channel_glb(struct ltt_ust_session *usess, struct ltt_ust_channel *uchan)
 {
        int ret = 0;
-       struct lttng_ht_iter iter;
-       struct ust_app *app;
        struct ust_app_session *ua_sess;
 
        LTTNG_ASSERT(usess->active);
        struct ust_app_session *ua_sess;
 
        LTTNG_ASSERT(usess->active);
@@ -4899,10 +4885,10 @@ int ust_app_enable_channel_glb(struct ltt_ust_session *usess, struct ltt_ust_cha
             uchan->name,
             usess->id);
 
             uchan->name,
             usess->id);
 
-       rcu_read_lock();
-
        /* For every registered applications */
        /* For every registered applications */
-       cds_lfht_for_each_entry (ust_app_ht->ht, &iter.iter, app, pid_n.node) {
+       for (auto *app :
+            lttng::urcu::lfht_iteration_adapter<ust_app, decltype(ust_app::pid_n), &ust_app::pid_n>(
+                    *ust_app_ht->ht)) {
                if (!app->compatible) {
                        /*
                         * TODO: In time, we should notice the caller of this error by
                if (!app->compatible) {
                        /*
                         * TODO: In time, we should notice the caller of this error by
@@ -4910,20 +4896,19 @@ int ust_app_enable_channel_glb(struct ltt_ust_session *usess, struct ltt_ust_cha
                         */
                        continue;
                }
                         */
                        continue;
                }
-               ua_sess = lookup_session_by_app(usess, app);
+               ua_sess = ust_app_lookup_app_session(usess, app);
                if (ua_sess == nullptr) {
                        continue;
                }
 
                /* Enable channel onto application */
                if (ua_sess == nullptr) {
                        continue;
                }
 
                /* Enable channel onto application */
-               ret = enable_ust_app_channel(ua_sess, uchan, app);
+               ret = enable_ust_app_channel(ua_sess->lock(), uchan, app);
                if (ret < 0) {
                        /* XXX: We might want to report this error at some point... */
                        continue;
                }
        }
 
                if (ret < 0) {
                        /* XXX: We might want to report this error at some point... */
                        continue;
                }
        }
 
-       rcu_read_unlock();
        return ret;
 }
 
        return ret;
 }
 
@@ -4935,9 +4920,8 @@ int ust_app_disable_event_glb(struct ltt_ust_session *usess,
                              struct ltt_ust_event *uevent)
 {
        int ret = 0;
                              struct ltt_ust_event *uevent)
 {
        int ret = 0;
-       struct lttng_ht_iter iter, uiter;
+       struct lttng_ht_iter uiter;
        struct lttng_ht_node_str *ua_chan_node;
        struct lttng_ht_node_str *ua_chan_node;
-       struct ust_app *app;
        struct ust_app_session *ua_sess;
        struct ust_app_channel *ua_chan;
        struct ust_app_event *ua_event;
        struct ust_app_session *ua_sess;
        struct ust_app_channel *ua_chan;
        struct ust_app_event *ua_event;
@@ -4949,18 +4933,14 @@ int ust_app_disable_event_glb(struct ltt_ust_session *usess,
            uchan->name,
            usess->id);
 
            uchan->name,
            usess->id);
 
-       rcu_read_lock();
-
-       /* For all registered applications */
-       cds_lfht_for_each_entry (ust_app_ht->ht, &iter.iter, app, pid_n.node) {
+       /* Iterate on all apps. */
+       for (auto *app :
+            lttng::urcu::lfht_iteration_adapter<ust_app, decltype(ust_app::pid_n), &ust_app::pid_n>(
+                    *ust_app_ht->ht)) {
                if (!app->compatible) {
                if (!app->compatible) {
-                       /*
-                        * TODO: In time, we should notice the caller of this error by
-                        * telling him that this is a version error.
-                        */
                        continue;
                }
                        continue;
                }
-               ua_sess = lookup_session_by_app(usess, app);
+               ua_sess = ust_app_lookup_app_session(usess, app);
                if (ua_sess == nullptr) {
                        /* Next app */
                        continue;
                if (ua_sess == nullptr) {
                        /* Next app */
                        continue;
@@ -4968,7 +4948,7 @@ int ust_app_disable_event_glb(struct ltt_ust_session *usess,
 
                /* Lookup channel in the ust app session */
                lttng_ht_lookup(ua_sess->channels, (void *) uchan->name, &uiter);
 
                /* Lookup channel in the ust app session */
                lttng_ht_lookup(ua_sess->channels, (void *) uchan->name, &uiter);
-               ua_chan_node = lttng_ht_iter_get_node_str(&uiter);
+               ua_chan_node = lttng_ht_iter_get_node<lttng_ht_node_str>(&uiter);
                if (ua_chan_node == nullptr) {
                        DBG2("Channel %s not found in session id %" PRIu64 " for app pid %d."
                             "Skipping",
                if (ua_chan_node == nullptr) {
                        DBG2("Channel %s not found in session id %" PRIu64 " for app pid %d."
                             "Skipping",
@@ -4979,11 +4959,13 @@ int ust_app_disable_event_glb(struct ltt_ust_session *usess,
                }
                ua_chan = lttng::utils::container_of(ua_chan_node, &ust_app_channel::node);
 
                }
                ua_chan = lttng::utils::container_of(ua_chan_node, &ust_app_channel::node);
 
-               ua_event = find_ust_app_event(ua_chan->events,
-                                             uevent->attr.name,
-                                             uevent->filter,
-                                             uevent->attr.loglevel,
-                                             uevent->exclusion);
+               ua_event = find_ust_app_event(
+                       ua_chan->events,
+                       uevent->attr.name,
+                       uevent->filter,
+                       (enum lttng_ust_abi_loglevel_type) uevent->attr.loglevel_type,
+                       uevent->attr.loglevel,
+                       uevent->exclusion);
                if (ua_event == nullptr) {
                        DBG2("Event %s not found in channel %s for app pid %d."
                             "Skipping",
                if (ua_event == nullptr) {
                        DBG2("Event %s not found in channel %s for app pid %d."
                             "Skipping",
@@ -4995,18 +4977,16 @@ int ust_app_disable_event_glb(struct ltt_ust_session *usess,
 
                ret = disable_ust_app_event(ua_event, app);
                if (ret < 0) {
 
                ret = disable_ust_app_event(ua_event, app);
                if (ret < 0) {
-                       /* XXX: Report error someday... */
                        continue;
                }
        }
 
                        continue;
                }
        }
 
-       rcu_read_unlock();
        return ret;
 }
 
 /* The ua_sess lock must be held by the caller.  */
 static int ust_app_channel_create(struct ltt_ust_session *usess,
        return ret;
 }
 
 /* The ua_sess lock must be held by the caller.  */
 static int ust_app_channel_create(struct ltt_ust_session *usess,
-                                 struct ust_app_session *ua_sess,
+                                 const ust_app_session::locked_weak_ref& ua_sess,
                                  struct ltt_ust_channel *uchan,
                                  struct ust_app *app,
                                  struct ust_app_channel **_ua_chan)
                                  struct ltt_ust_channel *uchan,
                                  struct ust_app *app,
                                  struct ust_app_channel **_ua_chan)
@@ -5014,15 +4994,10 @@ static int ust_app_channel_create(struct ltt_ust_session *usess,
        int ret = 0;
        struct ust_app_channel *ua_chan = nullptr;
 
        int ret = 0;
        struct ust_app_channel *ua_chan = nullptr;
 
-       LTTNG_ASSERT(ua_sess);
-       ASSERT_LOCKED(ua_sess->lock);
-
        if (!strncmp(uchan->name, DEFAULT_METADATA_NAME, sizeof(uchan->name))) {
                copy_channel_attr_to_ustctl(&ua_sess->metadata_attr, &uchan->attr);
                ret = 0;
        } else {
        if (!strncmp(uchan->name, DEFAULT_METADATA_NAME, sizeof(uchan->name))) {
                copy_channel_attr_to_ustctl(&ua_sess->metadata_attr, &uchan->attr);
                ret = 0;
        } else {
-               struct ltt_ust_context *uctx = nullptr;
-
                /*
                 * Create channel onto application and synchronize its
                 * configuration.
                /*
                 * Create channel onto application and synchronize its
                 * configuration.
@@ -5039,7 +5014,9 @@ static int ust_app_channel_create(struct ltt_ust_session *usess,
                }
 
                /* Add contexts. */
                }
 
                /* Add contexts. */
-               cds_list_for_each_entry (uctx, &uchan->ctx_list, list) {
+               for (auto *uctx :
+                    lttng::urcu::list_iteration_adapter<ltt_ust_context, &ltt_ust_context::list>(
+                            uchan->ctx_list)) {
                        ret = create_ust_app_channel_context(ua_chan, &uctx->ctx, app);
                        if (ret) {
                                goto error;
                        ret = create_ust_app_channel_context(ua_chan, &uctx->ctx, app);
                        if (ret) {
                                goto error;
@@ -5083,9 +5060,8 @@ int ust_app_enable_event_glb(struct ltt_ust_session *usess,
                             struct ltt_ust_event *uevent)
 {
        int ret = 0;
                             struct ltt_ust_event *uevent)
 {
        int ret = 0;
-       struct lttng_ht_iter iter, uiter;
+       struct lttng_ht_iter uiter;
        struct lttng_ht_node_str *ua_chan_node;
        struct lttng_ht_node_str *ua_chan_node;
-       struct ust_app *app;
        struct ust_app_session *ua_sess;
        struct ust_app_channel *ua_chan;
        struct ust_app_event *ua_event;
        struct ust_app_session *ua_sess;
        struct ust_app_channel *ua_chan;
        struct ust_app_event *ua_event;
@@ -5101,10 +5077,10 @@ int ust_app_enable_event_glb(struct ltt_ust_session *usess,
         * tracer also.
         */
 
         * tracer also.
         */
 
-       rcu_read_lock();
-
-       /* For all registered applications */
-       cds_lfht_for_each_entry (ust_app_ht->ht, &iter.iter, app, pid_n.node) {
+       /* Iterate on all apps. */
+       for (auto *app :
+            lttng::urcu::lfht_iteration_adapter<ust_app, decltype(ust_app::pid_n), &ust_app::pid_n>(
+                    *ust_app_ht->ht)) {
                if (!app->compatible) {
                        /*
                         * TODO: In time, we should notice the caller of this error by
                if (!app->compatible) {
                        /*
                         * TODO: In time, we should notice the caller of this error by
@@ -5112,59 +5088,53 @@ int ust_app_enable_event_glb(struct ltt_ust_session *usess,
                         */
                        continue;
                }
                         */
                        continue;
                }
-               ua_sess = lookup_session_by_app(usess, app);
+               ua_sess = ust_app_lookup_app_session(usess, app);
                if (!ua_sess) {
                        /* The application has problem or is probably dead. */
                        continue;
                }
 
                if (!ua_sess) {
                        /* The application has problem or is probably dead. */
                        continue;
                }
 
-               pthread_mutex_lock(&ua_sess->lock);
-
+               auto locked_ua_sess = ua_sess->lock();
                if (ua_sess->deleted) {
                if (ua_sess->deleted) {
-                       pthread_mutex_unlock(&ua_sess->lock);
                        continue;
                }
 
                /* Lookup channel in the ust app session */
                lttng_ht_lookup(ua_sess->channels, (void *) uchan->name, &uiter);
                        continue;
                }
 
                /* Lookup channel in the ust app session */
                lttng_ht_lookup(ua_sess->channels, (void *) uchan->name, &uiter);
-               ua_chan_node = lttng_ht_iter_get_node_str(&uiter);
+               ua_chan_node = lttng_ht_iter_get_node<lttng_ht_node_str>(&uiter);
                /*
                 * It is possible that the channel cannot be found is
                 * the channel/event creation occurs concurrently with
                 * an application exit.
                 */
                if (!ua_chan_node) {
                /*
                 * It is possible that the channel cannot be found is
                 * the channel/event creation occurs concurrently with
                 * an application exit.
                 */
                if (!ua_chan_node) {
-                       pthread_mutex_unlock(&ua_sess->lock);
                        continue;
                }
 
                ua_chan = lttng::utils::container_of(ua_chan_node, &ust_app_channel::node);
 
                /* Get event node */
                        continue;
                }
 
                ua_chan = lttng::utils::container_of(ua_chan_node, &ust_app_channel::node);
 
                /* Get event node */
-               ua_event = find_ust_app_event(ua_chan->events,
-                                             uevent->attr.name,
-                                             uevent->filter,
-                                             uevent->attr.loglevel,
-                                             uevent->exclusion);
+               ua_event = find_ust_app_event(
+                       ua_chan->events,
+                       uevent->attr.name,
+                       uevent->filter,
+                       (enum lttng_ust_abi_loglevel_type) uevent->attr.loglevel_type,
+                       uevent->attr.loglevel,
+                       uevent->exclusion);
                if (ua_event == nullptr) {
                        DBG3("UST app enable event %s not found for app PID %d."
                             "Skipping app",
                             uevent->attr.name,
                             app->pid);
                if (ua_event == nullptr) {
                        DBG3("UST app enable event %s not found for app PID %d."
                             "Skipping app",
                             uevent->attr.name,
                             app->pid);
-                       goto next_app;
+                       continue;
                }
 
                ret = enable_ust_app_event(ua_event, app);
                if (ret < 0) {
                }
 
                ret = enable_ust_app_event(ua_event, app);
                if (ret < 0) {
-                       pthread_mutex_unlock(&ua_sess->lock);
                        goto error;
                }
                        goto error;
                }
-       next_app:
-               pthread_mutex_unlock(&ua_sess->lock);
        }
        }
-
 error:
 error:
-       rcu_read_unlock();
        return ret;
 }
 
        return ret;
 }
 
@@ -5177,9 +5147,8 @@ int ust_app_create_event_glb(struct ltt_ust_session *usess,
                             struct ltt_ust_event *uevent)
 {
        int ret = 0;
                             struct ltt_ust_event *uevent)
 {
        int ret = 0;
-       struct lttng_ht_iter iter, uiter;
+       struct lttng_ht_iter uiter;
        struct lttng_ht_node_str *ua_chan_node;
        struct lttng_ht_node_str *ua_chan_node;
-       struct ust_app *app;
        struct ust_app_session *ua_sess;
        struct ust_app_channel *ua_chan;
 
        struct ust_app_session *ua_sess;
        struct ust_app_channel *ua_chan;
 
@@ -5188,10 +5157,10 @@ int ust_app_create_event_glb(struct ltt_ust_session *usess,
            uevent->attr.name,
            usess->id);
 
            uevent->attr.name,
            usess->id);
 
-       rcu_read_lock();
-
-       /* For all registered applications */
-       cds_lfht_for_each_entry (ust_app_ht->ht, &iter.iter, app, pid_n.node) {
+       /* Iterate on all apps. */
+       for (auto *app :
+            lttng::urcu::lfht_iteration_adapter<ust_app, decltype(ust_app::pid_n), &ust_app::pid_n>(
+                    *ust_app_ht->ht)) {
                if (!app->compatible) {
                        /*
                         * TODO: In time, we should notice the caller of this error by
                if (!app->compatible) {
                        /*
                         * TODO: In time, we should notice the caller of this error by
@@ -5199,34 +5168,34 @@ int ust_app_create_event_glb(struct ltt_ust_session *usess,
                         */
                        continue;
                }
                         */
                        continue;
                }
-               ua_sess = lookup_session_by_app(usess, app);
+
+               ua_sess = ust_app_lookup_app_session(usess, app);
                if (!ua_sess) {
                        /* The application has problem or is probably dead. */
                        continue;
                }
 
                if (!ua_sess) {
                        /* The application has problem or is probably dead. */
                        continue;
                }
 
-               pthread_mutex_lock(&ua_sess->lock);
+               auto locked_ua_sess = ua_sess->lock();
 
 
-               if (ua_sess->deleted) {
-                       pthread_mutex_unlock(&ua_sess->lock);
+               if (locked_ua_sess->deleted) {
                        continue;
                }
 
                /* Lookup channel in the ust app session */
                lttng_ht_lookup(ua_sess->channels, (void *) uchan->name, &uiter);
                        continue;
                }
 
                /* Lookup channel in the ust app session */
                lttng_ht_lookup(ua_sess->channels, (void *) uchan->name, &uiter);
-               ua_chan_node = lttng_ht_iter_get_node_str(&uiter);
+               ua_chan_node = lttng_ht_iter_get_node<lttng_ht_node_str>(&uiter);
                /* If the channel is not found, there is a code flow error */
                LTTNG_ASSERT(ua_chan_node);
 
                ua_chan = lttng::utils::container_of(ua_chan_node, &ust_app_channel::node);
 
                ret = create_ust_app_event(ua_chan, uevent, app);
                /* If the channel is not found, there is a code flow error */
                LTTNG_ASSERT(ua_chan_node);
 
                ua_chan = lttng::utils::container_of(ua_chan_node, &ust_app_channel::node);
 
                ret = create_ust_app_event(ua_chan, uevent, app);
-               pthread_mutex_unlock(&ua_sess->lock);
                if (ret < 0) {
                        if (ret != -LTTNG_UST_ERR_EXIST) {
                                /* Possible value at this point: -ENOMEM. If so, we stop! */
                                break;
                        }
                if (ret < 0) {
                        if (ret != -LTTNG_UST_ERR_EXIST) {
                                /* Possible value at this point: -ENOMEM. If so, we stop! */
                                break;
                        }
+
                        DBG2("UST app event %s already exist on app PID %d",
                             uevent->attr.name,
                             app->pid);
                        DBG2("UST app event %s already exist on app PID %d",
                             uevent->attr.name,
                             app->pid);
@@ -5234,7 +5203,6 @@ int ust_app_create_event_glb(struct ltt_ust_session *usess,
                }
        }
 
                }
        }
 
-       rcu_read_unlock();
        return ret;
 }
 
        return ret;
 }
 
@@ -5251,38 +5219,30 @@ static int ust_app_start_trace(struct ltt_ust_session *usess, struct ust_app *ap
 
        DBG("Starting tracing for ust app pid %d", app->pid);
 
 
        DBG("Starting tracing for ust app pid %d", app->pid);
 
-       rcu_read_lock();
+       const lttng::urcu::read_lock_guard read_lock;
+       const auto update_health_code_on_exit =
+               lttng::make_scope_exit([]() noexcept { health_code_update(); });
 
        if (!app->compatible) {
 
        if (!app->compatible) {
-               goto end;
+               return 0;
        }
 
        }
 
-       ua_sess = lookup_session_by_app(usess, app);
+       ua_sess = ust_app_lookup_app_session(usess, app);
        if (ua_sess == nullptr) {
                /* The session is in teardown process. Ignore and continue. */
        if (ua_sess == nullptr) {
                /* The session is in teardown process. Ignore and continue. */
-               goto end;
+               return 0;
        }
 
        }
 
-       pthread_mutex_lock(&ua_sess->lock);
-
-       if (ua_sess->deleted) {
-               pthread_mutex_unlock(&ua_sess->lock);
-               goto end;
-       }
+       auto locked_ua_sess = ua_sess->lock();
 
 
-       if (ua_sess->enabled) {
-               pthread_mutex_unlock(&ua_sess->lock);
-               goto end;
+       if (locked_ua_sess->deleted) {
+               return 0;
        }
 
        }
 
-       /* Upon restart, we skip the setup, already done */
-       if (ua_sess->started) {
-               goto skip_setup;
+       if (locked_ua_sess->enabled) {
+               return 0;
        }
 
        }
 
-       health_code_update();
-
-skip_setup:
        /* This starts the UST tracing */
        pthread_mutex_lock(&app->sock_lock);
        ret = lttng_ust_ctl_start_session(app->sock, ua_sess->handle);
        /* This starts the UST tracing */
        pthread_mutex_lock(&app->sock_lock);
        ret = lttng_ust_ctl_start_session(app->sock, ua_sess->handle);
@@ -5292,14 +5252,12 @@ skip_setup:
                        DBG3("UST app start session failed. Application is dead: pid = %d, sock = %d",
                             app->pid,
                             app->sock);
                        DBG3("UST app start session failed. Application is dead: pid = %d, sock = %d",
                             app->pid,
                             app->sock);
-                       pthread_mutex_unlock(&ua_sess->lock);
-                       goto end;
+                       return 0;
                } else if (ret == -EAGAIN) {
                        WARN("UST app start session failed. Communication time out: pid = %d, sock = %d",
                             app->pid,
                             app->sock);
                } else if (ret == -EAGAIN) {
                        WARN("UST app start session failed. Communication time out: pid = %d, sock = %d",
                             app->pid,
                             app->sock);
-                       pthread_mutex_unlock(&ua_sess->lock);
-                       goto end;
+                       return 0;
 
                } else {
                        ERR("UST app start session failed with ret %d: pid = %d, sock = %d",
 
                } else {
                        ERR("UST app start session failed with ret %d: pid = %d, sock = %d",
@@ -5307,14 +5265,13 @@ skip_setup:
                            app->pid,
                            app->sock);
                }
                            app->pid,
                            app->sock);
                }
-               goto error_unlock;
+
+               return -1;
        }
 
        /* Indicate that the session has been started once */
        }
 
        /* Indicate that the session has been started once */
-       ua_sess->started = 1;
-       ua_sess->enabled = 1;
-
-       pthread_mutex_unlock(&ua_sess->lock);
+       ua_sess->started = true;
+       ua_sess->enabled = true;
 
        health_code_update();
 
 
        health_code_update();
 
@@ -5339,16 +5296,7 @@ skip_setup:
                }
        }
 
                }
        }
 
-end:
-       rcu_read_unlock();
-       health_code_update();
        return 0;
        return 0;
-
-error_unlock:
-       pthread_mutex_unlock(&ua_sess->lock);
-       rcu_read_unlock();
-       health_code_update();
-       return -1;
 }
 
 /*
 }
 
 /*
@@ -5361,22 +5309,23 @@ static int ust_app_stop_trace(struct ltt_ust_session *usess, struct ust_app *app
 
        DBG("Stopping tracing for ust app pid %d", app->pid);
 
 
        DBG("Stopping tracing for ust app pid %d", app->pid);
 
-       rcu_read_lock();
+       const lttng::urcu::read_lock_guard read_lock;
+       const auto update_health_code_on_exit =
+               lttng::make_scope_exit([]() noexcept { health_code_update(); });
 
        if (!app->compatible) {
 
        if (!app->compatible) {
-               goto end_no_session;
+               return 0;
        }
 
        }
 
-       ua_sess = lookup_session_by_app(usess, app);
+       ua_sess = ust_app_lookup_app_session(usess, app);
        if (ua_sess == nullptr) {
        if (ua_sess == nullptr) {
-               goto end_no_session;
+               return 0;
        }
 
        }
 
-       pthread_mutex_lock(&ua_sess->lock);
+       auto locked_ua_sess = ua_sess->lock();
 
        if (ua_sess->deleted) {
 
        if (ua_sess->deleted) {
-               pthread_mutex_unlock(&ua_sess->lock);
-               goto end_no_session;
+               return 0;
        }
 
        /*
        }
 
        /*
@@ -5386,7 +5335,7 @@ static int ust_app_stop_trace(struct ltt_ust_session *usess, struct ust_app *app
         * indicate that this is a stop error.
         */
        if (!ua_sess->started) {
         * indicate that this is a stop error.
         */
        if (!ua_sess->started) {
-               goto error_rcu_unlock;
+               return -1;
        }
 
        health_code_update();
        }
 
        health_code_update();
@@ -5400,12 +5349,12 @@ static int ust_app_stop_trace(struct ltt_ust_session *usess, struct ust_app *app
                        DBG3("UST app stop session failed. Application is dead: pid = %d, sock = %d",
                             app->pid,
                             app->sock);
                        DBG3("UST app stop session failed. Application is dead: pid = %d, sock = %d",
                             app->pid,
                             app->sock);
-                       goto end_unlock;
+                       return 0;
                } else if (ret == -EAGAIN) {
                        WARN("UST app stop session failed. Communication time out: pid = %d, sock = %d",
                             app->pid,
                             app->sock);
                } else if (ret == -EAGAIN) {
                        WARN("UST app stop session failed. Communication time out: pid = %d, sock = %d",
                             app->pid,
                             app->sock);
-                       goto end_unlock;
+                       return 0;
 
                } else {
                        ERR("UST app stop session failed with ret %d: pid = %d, sock = %d",
 
                } else {
                        ERR("UST app stop session failed with ret %d: pid = %d, sock = %d",
@@ -5413,11 +5362,12 @@ static int ust_app_stop_trace(struct ltt_ust_session *usess, struct ust_app *app
                            app->pid,
                            app->sock);
                }
                            app->pid,
                            app->sock);
                }
-               goto error_rcu_unlock;
+
+               return -1;
        }
 
        health_code_update();
        }
 
        health_code_update();
-       ua_sess->enabled = 0;
+       ua_sess->enabled = false;
 
        /* Quiescent wait after stopping trace */
        pthread_mutex_lock(&app->sock_lock);
 
        /* Quiescent wait after stopping trace */
        pthread_mutex_lock(&app->sock_lock);
@@ -5443,7 +5393,8 @@ static int ust_app_stop_trace(struct ltt_ust_session *usess, struct ust_app *app
        health_code_update();
 
        {
        health_code_update();
 
        {
-               auto locked_registry = get_locked_session_registry(ua_sess);
+               auto locked_registry =
+                       get_locked_session_registry(locked_ua_sess->get_identifier());
 
                /* The UST app session is held registry shall not be null. */
                LTTNG_ASSERT(locked_registry);
 
                /* The UST app session is held registry shall not be null. */
                LTTNG_ASSERT(locked_registry);
@@ -5452,50 +5403,42 @@ static int ust_app_stop_trace(struct ltt_ust_session *usess, struct ust_app *app
                (void) push_metadata(locked_registry, ua_sess->consumer);
        }
 
                (void) push_metadata(locked_registry, ua_sess->consumer);
        }
 
-end_unlock:
-       pthread_mutex_unlock(&ua_sess->lock);
-end_no_session:
-       rcu_read_unlock();
-       health_code_update();
        return 0;
        return 0;
-
-error_rcu_unlock:
-       pthread_mutex_unlock(&ua_sess->lock);
-       rcu_read_unlock();
-       health_code_update();
-       return -1;
 }
 
 }
 
-static int ust_app_flush_app_session(struct ust_app *app, struct ust_app_session *ua_sess)
+static int ust_app_flush_app_session(ust_app& app, ust_app_session& ua_sess)
 {
        int ret, retval = 0;
 {
        int ret, retval = 0;
-       struct lttng_ht_iter iter;
-       struct ust_app_channel *ua_chan;
        struct consumer_socket *socket;
 
        struct consumer_socket *socket;
 
-       DBG("Flushing app session buffers for ust app pid %d", app->pid);
+       const auto update_health_code_on_exit =
+               lttng::make_scope_exit([]() noexcept { health_code_update(); });
 
 
-       rcu_read_lock();
+       DBG("Flushing app session buffers for ust app pid %d", app.pid);
 
 
-       if (!app->compatible) {
-               goto end_not_compatible;
+       if (!app.compatible) {
+               return 0;
        }
 
        }
 
-       pthread_mutex_lock(&ua_sess->lock);
-
-       if (ua_sess->deleted) {
-               goto end_deleted;
+       const auto locked_ua_sess = ua_sess.lock();
+       if (locked_ua_sess->deleted) {
+               return 0;
        }
 
        health_code_update();
 
        /* Flushing buffers */
        }
 
        health_code_update();
 
        /* Flushing buffers */
-       socket = consumer_find_socket_by_bitness(app->abi.bits_per_long, ua_sess->consumer);
+       socket = consumer_find_socket_by_bitness(app.abi.bits_per_long, ua_sess.consumer);
 
        /* Flush buffers and push metadata. */
 
        /* Flush buffers and push metadata. */
-       switch (ua_sess->buffer_type) {
+       switch (ua_sess.buffer_type) {
        case LTTNG_BUFFER_PER_PID:
        case LTTNG_BUFFER_PER_PID:
-               cds_lfht_for_each_entry (ua_sess->channels->ht, &iter.iter, ua_chan, node.node) {
+       {
+               for (auto *ua_chan :
+                    lttng::urcu::lfht_iteration_adapter<ust_app_channel,
+                                                        decltype(ust_app_channel::node),
+                                                        &ust_app_channel::node>(
+                            *ua_sess.channels->ht)) {
                        health_code_update();
                        ret = consumer_flush_channel(socket, ua_chan->key);
                        if (ret) {
                        health_code_update();
                        ret = consumer_flush_channel(socket, ua_chan->key);
                        if (ret) {
@@ -5504,21 +5447,15 @@ static int ust_app_flush_app_session(struct ust_app *app, struct ust_app_session
                                continue;
                        }
                }
                                continue;
                        }
                }
+
                break;
                break;
+       }
        case LTTNG_BUFFER_PER_UID:
        default:
                abort();
                break;
        }
 
        case LTTNG_BUFFER_PER_UID:
        default:
                abort();
                break;
        }
 
-       health_code_update();
-
-end_deleted:
-       pthread_mutex_unlock(&ua_sess->lock);
-
-end_not_compatible:
-       rcu_read_unlock();
-       health_code_update();
        return retval;
 }
 
        return retval;
 }
 
@@ -5533,19 +5470,16 @@ static int ust_app_flush_session(struct ltt_ust_session *usess)
 
        DBG("Flushing session buffers for all ust apps");
 
 
        DBG("Flushing session buffers for all ust apps");
 
-       rcu_read_lock();
-
        /* Flush buffers and push metadata. */
        switch (usess->buffer_type) {
        case LTTNG_BUFFER_PER_UID:
        {
        /* Flush buffers and push metadata. */
        switch (usess->buffer_type) {
        case LTTNG_BUFFER_PER_UID:
        {
-               struct buffer_reg_uid *reg;
-               struct lttng_ht_iter iter;
-
                /* Flush all per UID buffers associated to that session. */
                /* Flush all per UID buffers associated to that session. */
-               cds_list_for_each_entry (reg, &usess->buffer_reg_uid_list, lnode) {
+               for (auto *reg :
+                    lttng::urcu::list_iteration_adapter<buffer_reg_uid, &buffer_reg_uid::lnode>(
+                            usess->buffer_reg_uid_list)) {
+                       const lttng::urcu::read_lock_guard read_lock;
                        lsu::registry_session *ust_session_reg;
                        lsu::registry_session *ust_session_reg;
-                       struct buffer_reg_channel *buf_reg_chan;
                        struct consumer_socket *socket;
 
                        /* Get consumer socket to use to push the metadata.*/
                        struct consumer_socket *socket;
 
                        /* Get consumer socket to use to push the metadata.*/
@@ -5556,8 +5490,11 @@ static int ust_app_flush_session(struct ltt_ust_session *usess)
                                continue;
                        }
 
                                continue;
                        }
 
-                       cds_lfht_for_each_entry (
-                               reg->registry->channels->ht, &iter.iter, buf_reg_chan, node.node) {
+                       for (auto *buf_reg_chan :
+                            lttng::urcu::lfht_iteration_adapter<buffer_reg_channel,
+                                                                decltype(buffer_reg_channel::node),
+                                                                &buffer_reg_channel::node>(
+                                    *reg->registry->channels->ht)) {
                                /*
                                 * The following call will print error values so the return
                                 * code is of little importance because whatever happens, we
                                /*
                                 * The following call will print error values so the return
                                 * code is of little importance because whatever happens, we
@@ -5571,21 +5508,24 @@ static int ust_app_flush_session(struct ltt_ust_session *usess)
                        auto locked_registry = ust_session_reg->lock();
                        (void) push_metadata(locked_registry, usess->consumer);
                }
                        auto locked_registry = ust_session_reg->lock();
                        (void) push_metadata(locked_registry, usess->consumer);
                }
+
                break;
        }
        case LTTNG_BUFFER_PER_PID:
        {
                break;
        }
        case LTTNG_BUFFER_PER_PID:
        {
-               struct ust_app_session *ua_sess;
-               struct lttng_ht_iter iter;
-               struct ust_app *app;
-
-               cds_lfht_for_each_entry (ust_app_ht->ht, &iter.iter, app, pid_n.node) {
-                       ua_sess = lookup_session_by_app(usess, app);
+               /* Iterate on all apps. */
+               for (auto *app :
+                    lttng::urcu::lfht_iteration_adapter<ust_app,
+                                                        decltype(ust_app::pid_n),
+                                                        &ust_app::pid_n>(*ust_app_ht->ht)) {
+                       auto *ua_sess = ust_app_lookup_app_session(usess, app);
                        if (ua_sess == nullptr) {
                                continue;
                        }
                        if (ua_sess == nullptr) {
                                continue;
                        }
-                       (void) ust_app_flush_app_session(app, ua_sess);
+
+                       (void) ust_app_flush_app_session(*app, *ua_sess);
                }
                }
+
                break;
        }
        default:
                break;
        }
        default:
@@ -5594,7 +5534,6 @@ static int ust_app_flush_session(struct ltt_ust_session *usess)
                break;
        }
 
                break;
        }
 
-       rcu_read_unlock();
        health_code_update();
        return ret;
 }
        health_code_update();
        return ret;
 }
@@ -5602,22 +5541,21 @@ static int ust_app_flush_session(struct ltt_ust_session *usess)
 static int ust_app_clear_quiescent_app_session(struct ust_app *app, struct ust_app_session *ua_sess)
 {
        int ret = 0;
 static int ust_app_clear_quiescent_app_session(struct ust_app *app, struct ust_app_session *ua_sess)
 {
        int ret = 0;
-       struct lttng_ht_iter iter;
-       struct ust_app_channel *ua_chan;
        struct consumer_socket *socket;
 
        DBG("Clearing stream quiescent state for ust app pid %d", app->pid);
 
        struct consumer_socket *socket;
 
        DBG("Clearing stream quiescent state for ust app pid %d", app->pid);
 
-       rcu_read_lock();
+       const lttng::urcu::read_lock_guard read_lock;
+       const auto update_health_code_on_exit =
+               lttng::make_scope_exit([]() noexcept { health_code_update(); });
 
        if (!app->compatible) {
 
        if (!app->compatible) {
-               goto end_not_compatible;
+               return 0;
        }
 
        }
 
-       pthread_mutex_lock(&ua_sess->lock);
-
-       if (ua_sess->deleted) {
-               goto end_unlock;
+       const auto locked_ua_sess = ua_sess->lock();
+       if (locked_ua_sess->deleted) {
+               return 0;
        }
 
        health_code_update();
        }
 
        health_code_update();
@@ -5625,14 +5563,17 @@ static int ust_app_clear_quiescent_app_session(struct ust_app *app, struct ust_a
        socket = consumer_find_socket_by_bitness(app->abi.bits_per_long, ua_sess->consumer);
        if (!socket) {
                ERR("Failed to find consumer (%" PRIu32 ") socket", app->abi.bits_per_long);
        socket = consumer_find_socket_by_bitness(app->abi.bits_per_long, ua_sess->consumer);
        if (!socket) {
                ERR("Failed to find consumer (%" PRIu32 ") socket", app->abi.bits_per_long);
-               ret = -1;
-               goto end_unlock;
+               return -1;
        }
 
        /* Clear quiescent state. */
        switch (ua_sess->buffer_type) {
        case LTTNG_BUFFER_PER_PID:
        }
 
        /* Clear quiescent state. */
        switch (ua_sess->buffer_type) {
        case LTTNG_BUFFER_PER_PID:
-               cds_lfht_for_each_entry (ua_sess->channels->ht, &iter.iter, ua_chan, node.node) {
+               for (auto *ua_chan :
+                    lttng::urcu::lfht_iteration_adapter<ust_app_channel,
+                                                        decltype(ust_app_channel::node),
+                                                        &ust_app_channel::node>(
+                            *ua_sess->channels->ht)) {
                        health_code_update();
                        ret = consumer_clear_quiescent_channel(socket, ua_chan->key);
                        if (ret) {
                        health_code_update();
                        ret = consumer_clear_quiescent_channel(socket, ua_chan->key);
                        if (ret) {
@@ -5649,14 +5590,6 @@ static int ust_app_clear_quiescent_app_session(struct ust_app *app, struct ust_a
                break;
        }
 
                break;
        }
 
-       health_code_update();
-
-end_unlock:
-       pthread_mutex_unlock(&ua_sess->lock);
-
-end_not_compatible:
-       rcu_read_unlock();
-       health_code_update();
        return ret;
 }
 
        return ret;
 }
 
@@ -5672,21 +5605,18 @@ static int ust_app_clear_quiescent_session(struct ltt_ust_session *usess)
 
        DBG("Clearing stream quiescent state for all ust apps");
 
 
        DBG("Clearing stream quiescent state for all ust apps");
 
-       rcu_read_lock();
-
        switch (usess->buffer_type) {
        case LTTNG_BUFFER_PER_UID:
        {
        switch (usess->buffer_type) {
        case LTTNG_BUFFER_PER_UID:
        {
-               struct lttng_ht_iter iter;
-               struct buffer_reg_uid *reg;
-
                /*
                 * Clear quiescent for all per UID buffers associated to
                 * that session.
                 */
                /*
                 * Clear quiescent for all per UID buffers associated to
                 * that session.
                 */
-               cds_list_for_each_entry (reg, &usess->buffer_reg_uid_list, lnode) {
+               for (auto *reg :
+                    lttng::urcu::list_iteration_adapter<buffer_reg_uid, &buffer_reg_uid::lnode>(
+                            usess->buffer_reg_uid_list)) {
                        struct consumer_socket *socket;
                        struct consumer_socket *socket;
-                       struct buffer_reg_channel *buf_reg_chan;
+                       const lttng::urcu::read_lock_guard read_lock;
 
                        /* Get associated consumer socket.*/
                        socket = consumer_find_socket_by_bitness(reg->bits_per_long,
 
                        /* Get associated consumer socket.*/
                        socket = consumer_find_socket_by_bitness(reg->bits_per_long,
@@ -5699,8 +5629,11 @@ static int ust_app_clear_quiescent_session(struct ltt_ust_session *usess)
                                continue;
                        }
 
                                continue;
                        }
 
-                       cds_lfht_for_each_entry (
-                               reg->registry->channels->ht, &iter.iter, buf_reg_chan, node.node) {
+                       for (auto *buf_reg_chan :
+                            lttng::urcu::lfht_iteration_adapter<buffer_reg_channel,
+                                                                decltype(buffer_reg_channel::node),
+                                                                &buffer_reg_channel::node>(
+                                    *reg->registry->channels->ht)) {
                                /*
                                 * The following call will print error values so
                                 * the return code is of little importance
                                /*
                                 * The following call will print error values so
                                 * the return code is of little importance
@@ -5711,21 +5644,24 @@ static int ust_app_clear_quiescent_session(struct ltt_ust_session *usess)
                                                                        buf_reg_chan->consumer_key);
                        }
                }
                                                                        buf_reg_chan->consumer_key);
                        }
                }
+
                break;
        }
        case LTTNG_BUFFER_PER_PID:
        {
                break;
        }
        case LTTNG_BUFFER_PER_PID:
        {
-               struct ust_app_session *ua_sess;
-               struct lttng_ht_iter iter;
-               struct ust_app *app;
-
-               cds_lfht_for_each_entry (ust_app_ht->ht, &iter.iter, app, pid_n.node) {
-                       ua_sess = lookup_session_by_app(usess, app);
+               /* Iterate on all apps. */
+               for (auto *app :
+                    lttng::urcu::lfht_iteration_adapter<ust_app,
+                                                        decltype(ust_app::pid_n),
+                                                        &ust_app::pid_n>(*ust_app_ht->ht)) {
+                       auto *ua_sess = ust_app_lookup_app_session(usess, app);
                        if (ua_sess == nullptr) {
                                continue;
                        }
                        if (ua_sess == nullptr) {
                                continue;
                        }
+
                        (void) ust_app_clear_quiescent_app_session(app, ua_sess);
                }
                        (void) ust_app_clear_quiescent_app_session(app, ua_sess);
                }
+
                break;
        }
        default:
                break;
        }
        default:
@@ -5734,7 +5670,6 @@ static int ust_app_clear_quiescent_session(struct ltt_ust_session *usess)
                break;
        }
 
                break;
        }
 
-       rcu_read_unlock();
        health_code_update();
        return ret;
 }
        health_code_update();
        return ret;
 }
@@ -5751,14 +5686,14 @@ static int destroy_trace(struct ltt_ust_session *usess, struct ust_app *app)
 
        DBG("Destroy tracing for ust app pid %d", app->pid);
 
 
        DBG("Destroy tracing for ust app pid %d", app->pid);
 
-       rcu_read_lock();
+       const lttng::urcu::read_lock_guard read_lock;
 
        if (!app->compatible) {
                goto end;
        }
 
        __lookup_session_by_app(usess, app, &iter);
 
        if (!app->compatible) {
                goto end;
        }
 
        __lookup_session_by_app(usess, app, &iter);
-       node = lttng_ht_iter_get_node_u64(&iter);
+       node = lttng_ht_iter_get_node<lttng_ht_node_u64>(&iter);
        if (node == nullptr) {
                /* Session is being or is deleted. */
                goto end;
        if (node == nullptr) {
                /* Session is being or is deleted. */
                goto end;
@@ -5791,7 +5726,6 @@ static int destroy_trace(struct ltt_ust_session *usess, struct ust_app *app)
                }
        }
 end:
                }
        }
 end:
-       rcu_read_unlock();
        health_code_update();
        return 0;
 }
        health_code_update();
        return 0;
 }
@@ -5801,18 +5735,13 @@ end:
  */
 int ust_app_start_trace_all(struct ltt_ust_session *usess)
 {
  */
 int ust_app_start_trace_all(struct ltt_ust_session *usess)
 {
-       struct lttng_ht_iter iter;
-       struct ust_app *app;
-
        DBG("Starting all UST traces");
 
        /*
         * Even though the start trace might fail, flag this session active so
         * other application coming in are started by default.
         */
        DBG("Starting all UST traces");
 
        /*
         * Even though the start trace might fail, flag this session active so
         * other application coming in are started by default.
         */
-       usess->active = 1;
-
-       rcu_read_lock();
+       usess->active = true;
 
        /*
         * In a start-stop-start use-case, we need to clear the quiescent state
 
        /*
         * In a start-stop-start use-case, we need to clear the quiescent state
@@ -5822,12 +5751,13 @@ int ust_app_start_trace_all(struct ltt_ust_session *usess)
         */
        (void) ust_app_clear_quiescent_session(usess);
 
         */
        (void) ust_app_clear_quiescent_session(usess);
 
-       cds_lfht_for_each_entry (ust_app_ht->ht, &iter.iter, app, pid_n.node) {
+       /* Iterate on all apps. */
+       for (auto *app :
+            lttng::urcu::lfht_iteration_adapter<ust_app, decltype(ust_app::pid_n), &ust_app::pid_n>(
+                    *ust_app_ht->ht)) {
                ust_app_global_update(usess, app);
        }
 
                ust_app_global_update(usess, app);
        }
 
-       rcu_read_unlock();
-
        return 0;
 }
 
        return 0;
 }
 
@@ -5838,8 +5768,6 @@ int ust_app_start_trace_all(struct ltt_ust_session *usess)
 int ust_app_stop_trace_all(struct ltt_ust_session *usess)
 {
        int ret = 0;
 int ust_app_stop_trace_all(struct ltt_ust_session *usess)
 {
        int ret = 0;
-       struct lttng_ht_iter iter;
-       struct ust_app *app;
 
        DBG("Stopping all UST traces");
 
 
        DBG("Stopping all UST traces");
 
@@ -5847,11 +5775,12 @@ int ust_app_stop_trace_all(struct ltt_ust_session *usess)
         * Even though the stop trace might fail, flag this session inactive so
         * other application coming in are not started by default.
         */
         * Even though the stop trace might fail, flag this session inactive so
         * other application coming in are not started by default.
         */
-       usess->active = 0;
-
-       rcu_read_lock();
+       usess->active = false;
 
 
-       cds_lfht_for_each_entry (ust_app_ht->ht, &iter.iter, app, pid_n.node) {
+       /* Iterate on all apps. */
+       for (auto *app :
+            lttng::urcu::lfht_iteration_adapter<ust_app, decltype(ust_app::pid_n), &ust_app::pid_n>(
+                    *ust_app_ht->ht)) {
                ret = ust_app_stop_trace(usess, app);
                if (ret < 0) {
                        /* Continue to next apps even on error */
                ret = ust_app_stop_trace(usess, app);
                if (ret < 0) {
                        /* Continue to next apps even on error */
@@ -5861,8 +5790,6 @@ int ust_app_stop_trace_all(struct ltt_ust_session *usess)
 
        (void) ust_app_flush_session(usess);
 
 
        (void) ust_app_flush_session(usess);
 
-       rcu_read_unlock();
-
        return 0;
 }
 
        return 0;
 }
 
@@ -5871,30 +5798,21 @@ int ust_app_stop_trace_all(struct ltt_ust_session *usess)
  */
 int ust_app_destroy_trace_all(struct ltt_ust_session *usess)
 {
  */
 int ust_app_destroy_trace_all(struct ltt_ust_session *usess)
 {
-       int ret = 0;
-       struct lttng_ht_iter iter;
-       struct ust_app *app;
-
        DBG("Destroy all UST traces");
 
        DBG("Destroy all UST traces");
 
-       rcu_read_lock();
-
-       cds_lfht_for_each_entry (ust_app_ht->ht, &iter.iter, app, pid_n.node) {
-               ret = destroy_trace(usess, app);
-               if (ret < 0) {
-                       /* Continue to next apps even on error */
-                       continue;
-               }
+       /* Iterate on all apps. */
+       for (auto *app :
+            lttng::urcu::lfht_iteration_adapter<ust_app, decltype(ust_app::pid_n), &ust_app::pid_n>(
+                    *ust_app_ht->ht)) {
+               (void) destroy_trace(usess, app);
        }
 
        }
 
-       rcu_read_unlock();
-
        return 0;
 }
 
 /* The ua_sess lock must be held by the caller. */
 static int find_or_create_ust_app_channel(struct ltt_ust_session *usess,
        return 0;
 }
 
 /* The ua_sess lock must be held by the caller. */
 static int find_or_create_ust_app_channel(struct ltt_ust_session *usess,
-                                         struct ust_app_session *ua_sess,
+                                         const ust_app_session::locked_weak_ref& ua_sess,
                                          struct ust_app *app,
                                          struct ltt_ust_channel *uchan,
                                          struct ust_app_channel **ua_chan)
                                          struct ust_app *app,
                                          struct ltt_ust_channel *uchan,
                                          struct ust_app_channel **ua_chan)
@@ -5904,9 +5822,9 @@ static int find_or_create_ust_app_channel(struct ltt_ust_session *usess,
        struct lttng_ht_node_str *ua_chan_node;
 
        lttng_ht_lookup(ua_sess->channels, (void *) uchan->name, &iter);
        struct lttng_ht_node_str *ua_chan_node;
 
        lttng_ht_lookup(ua_sess->channels, (void *) uchan->name, &iter);
-       ua_chan_node = lttng_ht_iter_get_node_str(&iter);
+       ua_chan_node = lttng_ht_iter_get_node<lttng_ht_node_str>(&iter);
        if (ua_chan_node) {
        if (ua_chan_node) {
-               *ua_chan = caa_container_of(ua_chan_node, struct ust_app_channel, node);
+               *ua_chan = lttng::utils::container_of(ua_chan_node, &ust_app_channel::node);
                goto end;
        }
 
                goto end;
        }
 
@@ -5928,6 +5846,7 @@ static int ust_app_channel_synchronize_event(struct ust_app_channel *ua_chan,
        ua_event = find_ust_app_event(ua_chan->events,
                                      uevent->attr.name,
                                      uevent->filter,
        ua_event = find_ust_app_event(ua_chan->events,
                                      uevent->attr.name,
                                      uevent->filter,
+                                     (enum lttng_ust_abi_loglevel_type) uevent->attr.loglevel_type,
                                      uevent->attr.loglevel,
                                      uevent->exclusion);
        if (!ua_event) {
                                      uevent->attr.loglevel,
                                      uevent->exclusion);
        if (!ua_event) {
@@ -5952,9 +5871,7 @@ static void ust_app_synchronize_event_notifier_rules(struct ust_app *app)
        int ret = 0;
        enum lttng_error_code ret_code;
        enum lttng_trigger_status t_status;
        int ret = 0;
        enum lttng_error_code ret_code;
        enum lttng_trigger_status t_status;
-       struct lttng_ht_iter app_trigger_iter;
        struct lttng_triggers *triggers = nullptr;
        struct lttng_triggers *triggers = nullptr;
-       struct ust_app_event_notifier_rule *event_notifier_rule;
        unsigned int count, i;
 
        ASSERT_RCU_READ_LOCKED();
        unsigned int count, i;
 
        ASSERT_RCU_READ_LOCKED();
@@ -5995,8 +5912,8 @@ static void ust_app_synchronize_event_notifier_rules(struct ust_app *app)
        }
 
        for (i = 0; i < count; i++) {
        }
 
        for (i = 0; i < count; i++) {
-               struct lttng_condition *condition;
-               struct lttng_event_rule *event_rule;
+               const struct lttng_condition *condition;
+               const struct lttng_event_rule *event_rule;
                struct lttng_trigger *trigger;
                const struct ust_app_event_notifier_rule *looked_up_event_notifier_rule;
                enum lttng_condition_status condition_status;
                struct lttng_trigger *trigger;
                const struct ust_app_event_notifier_rule *looked_up_event_notifier_rule;
                enum lttng_condition_status condition_status;
@@ -6006,7 +5923,7 @@ static void ust_app_synchronize_event_notifier_rules(struct ust_app *app)
                LTTNG_ASSERT(trigger);
 
                token = lttng_trigger_get_tracer_token(trigger);
                LTTNG_ASSERT(trigger);
 
                token = lttng_trigger_get_tracer_token(trigger);
-               condition = lttng_trigger_get_condition(trigger);
+               condition = lttng_trigger_get_const_condition(trigger);
 
                if (lttng_condition_get_type(condition) !=
                    LTTNG_CONDITION_TYPE_EVENT_RULE_MATCHES) {
 
                if (lttng_condition_get_type(condition) !=
                    LTTNG_CONDITION_TYPE_EVENT_RULE_MATCHES) {
@@ -6014,8 +5931,8 @@ static void ust_app_synchronize_event_notifier_rules(struct ust_app *app)
                        continue;
                }
 
                        continue;
                }
 
-               condition_status = lttng_condition_event_rule_matches_borrow_rule_mutable(
-                       condition, &event_rule);
+               condition_status =
+                       lttng_condition_event_rule_matches_get_rule(condition, &event_rule);
                LTTNG_ASSERT(condition_status == LTTNG_CONDITION_STATUS_OK);
 
                if (lttng_event_rule_get_domain_type(event_rule) == LTTNG_DOMAIN_KERNEL) {
                LTTNG_ASSERT(condition_status == LTTNG_CONDITION_STATUS_OK);
 
                if (lttng_event_rule_get_domain_type(event_rule) == LTTNG_DOMAIN_KERNEL) {
@@ -6038,12 +5955,12 @@ static void ust_app_synchronize_event_notifier_rules(struct ust_app *app)
                }
        }
 
                }
        }
 
-       rcu_read_lock();
        /* Remove all unknown event sources from the app. */
        /* Remove all unknown event sources from the app. */
-       cds_lfht_for_each_entry (app->token_to_event_notifier_rule_ht->ht,
-                                &app_trigger_iter.iter,
-                                event_notifier_rule,
-                                node.node) {
+       for (auto *event_notifier_rule :
+            lttng::urcu::lfht_iteration_adapter<ust_app_event_notifier_rule,
+                                                decltype(ust_app_event_notifier_rule::node),
+                                                &ust_app_event_notifier_rule::node>(
+                    *app->token_to_event_notifier_rule_ht->ht)) {
                const uint64_t app_token = event_notifier_rule->token;
                bool found = false;
 
                const uint64_t app_token = event_notifier_rule->token;
                bool found = false;
 
@@ -6075,17 +5992,15 @@ static void ust_app_synchronize_event_notifier_rules(struct ust_app *app)
                 * This trigger was unregistered, disable it on the tracer's
                 * side.
                 */
                 * This trigger was unregistered, disable it on the tracer's
                 * side.
                 */
-               ret = lttng_ht_del(app->token_to_event_notifier_rule_ht, &app_trigger_iter);
+               ret = cds_lfht_del(app->token_to_event_notifier_rule_ht->ht,
+                                  &event_notifier_rule->node.node);
                LTTNG_ASSERT(ret == 0);
 
                /* Callee logs errors. */
                (void) disable_ust_object(app, event_notifier_rule->obj);
                LTTNG_ASSERT(ret == 0);
 
                /* Callee logs errors. */
                (void) disable_ust_object(app, event_notifier_rule->obj);
-
                delete_ust_app_event_notifier_rule(app->sock, event_notifier_rule, app);
        }
 
                delete_ust_app_event_notifier_rule(app->sock, event_notifier_rule, app);
        }
 
-       rcu_read_unlock();
-
 end:
        lttng_triggers_destroy(triggers);
        return;
 end:
        lttng_triggers_destroy(triggers);
        return;
@@ -6095,22 +6010,18 @@ end:
  * RCU read lock must be held by the caller.
  */
 static void ust_app_synchronize_all_channels(struct ltt_ust_session *usess,
  * RCU read lock must be held by the caller.
  */
 static void ust_app_synchronize_all_channels(struct ltt_ust_session *usess,
-                                            struct ust_app_session *ua_sess,
+                                            const ust_app_session::locked_weak_ref& ua_sess,
                                             struct ust_app *app)
 {
                                             struct ust_app *app)
 {
-       int ret = 0;
-       struct cds_lfht_iter uchan_iter;
-       struct ltt_ust_channel *uchan;
-
        LTTNG_ASSERT(usess);
        LTTNG_ASSERT(usess);
-       LTTNG_ASSERT(ua_sess);
        LTTNG_ASSERT(app);
        ASSERT_RCU_READ_LOCKED();
 
        LTTNG_ASSERT(app);
        ASSERT_RCU_READ_LOCKED();
 
-       cds_lfht_for_each_entry (usess->domain_global.channels->ht, &uchan_iter, uchan, node.node) {
+       for (auto *uchan : lttng::urcu::lfht_iteration_adapter<ltt_ust_channel,
+                                                              decltype(ltt_ust_channel::node),
+                                                              &ltt_ust_channel::node>(
+                    *usess->domain_global.channels->ht)) {
                struct ust_app_channel *ua_chan;
                struct ust_app_channel *ua_chan;
-               struct cds_lfht_iter uevent_iter;
-               struct ltt_ust_event *uevent;
 
                /*
                 * Search for a matching ust_app_channel. If none is found,
 
                /*
                 * Search for a matching ust_app_channel. If none is found,
@@ -6119,7 +6030,7 @@ static void ust_app_synchronize_all_channels(struct ltt_ust_session *usess,
                 * allocated (if necessary) and sent to the application, and
                 * all enabled contexts will be added to the channel.
                 */
                 * allocated (if necessary) and sent to the application, and
                 * all enabled contexts will be added to the channel.
                 */
-               ret = find_or_create_ust_app_channel(usess, ua_sess, app, uchan, &ua_chan);
+               int ret = find_or_create_ust_app_channel(usess, ua_sess, app, uchan, &ua_chan);
                if (ret) {
                        /* Tracer is probably gone or ENOMEM. */
                        goto end;
                if (ret) {
                        /* Tracer is probably gone or ENOMEM. */
                        goto end;
@@ -6130,7 +6041,11 @@ static void ust_app_synchronize_all_channels(struct ltt_ust_session *usess,
                        continue;
                }
 
                        continue;
                }
 
-               cds_lfht_for_each_entry (uchan->events->ht, &uevent_iter, uevent, node.node) {
+               for (auto *uevent :
+                    lttng::urcu::lfht_iteration_adapter<ltt_ust_event,
+                                                        decltype(ltt_ust_event::node),
+                                                        &ltt_ust_event::node>(
+                            *uchan->events->ht)) {
                        ret = ust_app_channel_synchronize_event(ua_chan, uevent, app);
                        if (ret) {
                                goto end;
                        ret = ust_app_channel_synchronize_event(ua_chan, uevent, app);
                        if (ret) {
                                goto end;
@@ -6167,51 +6082,44 @@ static void ust_app_synchronize(struct ltt_ust_session *usess, struct ust_app *a
        ret = find_or_create_ust_app_session(usess, app, &ua_sess, nullptr);
        if (ret < 0) {
                /* Tracer is probably gone or ENOMEM. */
        ret = find_or_create_ust_app_session(usess, app, &ua_sess, nullptr);
        if (ret < 0) {
                /* Tracer is probably gone or ENOMEM. */
-               if (ua_sess) {
-                       destroy_app_session(app, ua_sess);
-               }
-               goto end;
+               return;
        }
        }
+
        LTTNG_ASSERT(ua_sess);
 
        LTTNG_ASSERT(ua_sess);
 
-       pthread_mutex_lock(&ua_sess->lock);
-       if (ua_sess->deleted) {
-               goto deleted_session;
+       const auto locked_ua_sess = ua_sess->lock();
+       if (locked_ua_sess->deleted) {
+               return;
        }
 
        }
 
-       rcu_read_lock();
+       {
+               const lttng::urcu::read_lock_guard read_lock;
 
 
-       ust_app_synchronize_all_channels(usess, ua_sess, app);
+               ust_app_synchronize_all_channels(usess, locked_ua_sess, app);
 
 
-       /*
-        * Create the metadata for the application. This returns gracefully if a
-        * metadata was already set for the session.
-        *
-        * The metadata channel must be created after the data channels as the
-        * consumer daemon assumes this ordering. When interacting with a relay
-        * daemon, the consumer will use this assumption to send the
-        * "STREAMS_SENT" message to the relay daemon.
-        */
-       ret = create_ust_app_metadata(ua_sess, app, usess->consumer);
-       if (ret < 0) {
-               ERR("Metadata creation failed for app sock %d for session id %" PRIu64,
-                   app->sock,
-                   usess->id);
+               /*
+                * Create the metadata for the application. This returns gracefully if a
+                * metadata was already set for the session.
+                *
+                * The metadata channel must be created after the data channels as the
+                * consumer daemon assumes this ordering. When interacting with a relay
+                * daemon, the consumer will use this assumption to send the
+                * "STREAMS_SENT" message to the relay daemon.
+                */
+               ret = create_ust_app_metadata(locked_ua_sess, app, usess->consumer);
+               if (ret < 0) {
+                       ERR("Metadata creation failed for app sock %d for session id %" PRIu64,
+                           app->sock,
+                           usess->id);
+               }
        }
        }
-
-       rcu_read_unlock();
-
-deleted_session:
-       pthread_mutex_unlock(&ua_sess->lock);
-end:
-       return;
 }
 
 static void ust_app_global_destroy(struct ltt_ust_session *usess, struct ust_app *app)
 {
        struct ust_app_session *ua_sess;
 
 }
 
 static void ust_app_global_destroy(struct ltt_ust_session *usess, struct ust_app *app)
 {
        struct ust_app_session *ua_sess;
 
-       ua_sess = lookup_session_by_app(usess, app);
+       ua_sess = ust_app_lookup_app_session(usess, app);
        if (ua_sess == nullptr) {
                return;
        }
        if (ua_sess == nullptr) {
                return;
        }
@@ -6282,27 +6190,22 @@ void ust_app_global_update_event_notifier_rules(struct ust_app *app)
  */
 void ust_app_global_update_all(struct ltt_ust_session *usess)
 {
  */
 void ust_app_global_update_all(struct ltt_ust_session *usess)
 {
-       struct lttng_ht_iter iter;
-       struct ust_app *app;
-
-       rcu_read_lock();
-       cds_lfht_for_each_entry (ust_app_ht->ht, &iter.iter, app, pid_n.node) {
+       /* Iterate on all apps. */
+       for (auto *app :
+            lttng::urcu::lfht_iteration_adapter<ust_app, decltype(ust_app::pid_n), &ust_app::pid_n>(
+                    *ust_app_ht->ht)) {
                ust_app_global_update(usess, app);
        }
                ust_app_global_update(usess, app);
        }
-       rcu_read_unlock();
 }
 
 void ust_app_global_update_all_event_notifier_rules()
 {
 }
 
 void ust_app_global_update_all_event_notifier_rules()
 {
-       struct lttng_ht_iter iter;
-       struct ust_app *app;
-
-       rcu_read_lock();
-       cds_lfht_for_each_entry (ust_app_ht->ht, &iter.iter, app, pid_n.node) {
+       /* Iterate on all apps. */
+       for (auto *app :
+            lttng::urcu::lfht_iteration_adapter<ust_app, decltype(ust_app::pid_n), &ust_app::pid_n>(
+                    *ust_app_ht->ht)) {
                ust_app_global_update_event_notifier_rules(app);
        }
                ust_app_global_update_event_notifier_rules(app);
        }
-
-       rcu_read_unlock();
 }
 
 /*
 }
 
 /*
@@ -6314,15 +6217,16 @@ int ust_app_add_ctx_channel_glb(struct ltt_ust_session *usess,
 {
        int ret = 0;
        struct lttng_ht_node_str *ua_chan_node;
 {
        int ret = 0;
        struct lttng_ht_node_str *ua_chan_node;
-       struct lttng_ht_iter iter, uiter;
+       struct lttng_ht_iter uiter;
        struct ust_app_channel *ua_chan = nullptr;
        struct ust_app_session *ua_sess;
        struct ust_app_channel *ua_chan = nullptr;
        struct ust_app_session *ua_sess;
-       struct ust_app *app;
 
        LTTNG_ASSERT(usess->active);
 
 
        LTTNG_ASSERT(usess->active);
 
-       rcu_read_lock();
-       cds_lfht_for_each_entry (ust_app_ht->ht, &iter.iter, app, pid_n.node) {
+       /* Iterate on all apps. */
+       for (auto *app :
+            lttng::urcu::lfht_iteration_adapter<ust_app, decltype(ust_app::pid_n), &ust_app::pid_n>(
+                    *ust_app_ht->ht)) {
                if (!app->compatible) {
                        /*
                         * TODO: In time, we should notice the caller of this error by
                if (!app->compatible) {
                        /*
                         * TODO: In time, we should notice the caller of this error by
@@ -6330,34 +6234,29 @@ int ust_app_add_ctx_channel_glb(struct ltt_ust_session *usess,
                         */
                        continue;
                }
                         */
                        continue;
                }
-               ua_sess = lookup_session_by_app(usess, app);
+               ua_sess = ust_app_lookup_app_session(usess, app);
                if (ua_sess == nullptr) {
                        continue;
                }
 
                if (ua_sess == nullptr) {
                        continue;
                }
 
-               pthread_mutex_lock(&ua_sess->lock);
-
-               if (ua_sess->deleted) {
-                       pthread_mutex_unlock(&ua_sess->lock);
+               const auto locked_ua_sess = ua_sess->lock();
+               if (locked_ua_sess->deleted) {
                        continue;
                }
 
                /* Lookup channel in the ust app session */
                lttng_ht_lookup(ua_sess->channels, (void *) uchan->name, &uiter);
                        continue;
                }
 
                /* Lookup channel in the ust app session */
                lttng_ht_lookup(ua_sess->channels, (void *) uchan->name, &uiter);
-               ua_chan_node = lttng_ht_iter_get_node_str(&uiter);
+               ua_chan_node = lttng_ht_iter_get_node<lttng_ht_node_str>(&uiter);
                if (ua_chan_node == nullptr) {
                if (ua_chan_node == nullptr) {
-                       goto next_app;
+                       continue;
                }
                }
-               ua_chan = caa_container_of(ua_chan_node, struct ust_app_channel, node);
+               ua_chan = lttng::utils::container_of(ua_chan_node, &ust_app_channel::node);
                ret = create_ust_app_channel_context(ua_chan, &uctx->ctx, app);
                if (ret < 0) {
                ret = create_ust_app_channel_context(ua_chan, &uctx->ctx, app);
                if (ret < 0) {
-                       goto next_app;
+                       continue;
                }
                }
-       next_app:
-               pthread_mutex_unlock(&ua_sess->lock);
        }
 
        }
 
-       rcu_read_unlock();
        return ret;
 }
 
        return ret;
 }
 
@@ -6433,7 +6332,7 @@ static struct ust_app_session *find_session_by_objd(struct ust_app *app, int obj
        ASSERT_RCU_READ_LOCKED();
 
        lttng_ht_lookup(app->ust_sessions_objd, (void *) ((unsigned long) objd), &iter);
        ASSERT_RCU_READ_LOCKED();
 
        lttng_ht_lookup(app->ust_sessions_objd, (void *) ((unsigned long) objd), &iter);
-       node = lttng_ht_iter_get_node_ulong(&iter);
+       node = lttng_ht_iter_get_node<lttng_ht_node_ulong>(&iter);
        if (node == nullptr) {
                DBG2("UST app session find by objd %d not found", objd);
                goto error;
        if (node == nullptr) {
                DBG2("UST app session find by objd %d not found", objd);
                goto error;
@@ -6460,7 +6359,7 @@ static struct ust_app_channel *find_channel_by_objd(struct ust_app *app, int obj
        ASSERT_RCU_READ_LOCKED();
 
        lttng_ht_lookup(app->ust_objd, (void *) ((unsigned long) objd), &iter);
        ASSERT_RCU_READ_LOCKED();
 
        lttng_ht_lookup(app->ust_objd, (void *) ((unsigned long) objd), &iter);
-       node = lttng_ht_iter_get_node_ulong(&iter);
+       node = lttng_ht_iter_get_node<lttng_ht_node_ulong>(&iter);
        if (node == nullptr) {
                DBG2("UST app channel find by objd %d not found", objd);
                goto error;
        if (node == nullptr) {
                DBG2("UST app channel find by objd %d not found", objd);
                goto error;
@@ -6492,9 +6391,10 @@ static int handle_app_register_channel_notification(int sock,
        struct ust_app_channel *ua_chan;
        struct ust_app_session *ua_sess;
        auto ust_ctl_context_fields =
        struct ust_app_channel *ua_chan;
        struct ust_app_session *ua_sess;
        auto ust_ctl_context_fields =
-               lttng::make_unique_wrapper<lttng_ust_ctl_field, lttng::free>(raw_context_fields);
+               lttng::make_unique_wrapper<lttng_ust_ctl_field, lttng::memory::free>(
+                       raw_context_fields);
 
 
-       lttng::urcu::read_lock_guard read_lock_guard;
+       const lttng::urcu::read_lock_guard read_lock_guard;
 
        /* Lookup application. If not found, there is a code flow error. */
        app = find_app_by_notify_sock(sock);
 
        /* Lookup application. If not found, there is a code flow error. */
        app = find_app_by_notify_sock(sock);
@@ -6514,7 +6414,15 @@ static int handle_app_register_channel_notification(int sock,
        ua_sess = ua_chan->session;
 
        /* Get right session registry depending on the session buffer type. */
        ua_sess = ua_chan->session;
 
        /* Get right session registry depending on the session buffer type. */
-       auto locked_registry_session = get_locked_session_registry(ua_sess);
+
+       /*
+        * HACK: ua_sess is already locked by the client thread. This is called
+        * in the context of the handling of a notification from the application.
+        */
+       auto locked_ua_sess = ust_app_session::make_locked_weak_ref(*ua_sess);
+       auto locked_registry_session =
+               get_locked_session_registry(locked_ua_sess->get_identifier());
+       locked_ua_sess.release();
        if (!locked_registry_session) {
                DBG("Application session is being torn down. Abort event notify");
                return 0;
        if (!locked_registry_session) {
                DBG("Application session is being torn down. Abort event notify");
                return 0;
@@ -6586,7 +6494,7 @@ static int handle_app_register_channel_notification(int sock,
                                goto reply;
                        }
                }
                                goto reply;
                        }
                }
-       } catch (std::exception& ex) {
+       } catch (const std::exception& ex) {
                ERR("Failed to handle application context: %s", ex.what());
                ret_code = -EINVAL;
                goto reply;
                ERR("Failed to handle application context: %s", ex.what());
                ret_code = -EINVAL;
                goto reply;
@@ -6650,15 +6558,17 @@ static int add_event_ust_registry(int sock,
                                  char *raw_model_emf_uri)
 {
        int ret, ret_code;
                                  char *raw_model_emf_uri)
 {
        int ret, ret_code;
-       uint32_t event_id = 0;
+       lsu::event_id event_id = 0;
        uint64_t chan_reg_key;
        struct ust_app *app;
        struct ust_app_channel *ua_chan;
        struct ust_app_session *ua_sess;
        uint64_t chan_reg_key;
        struct ust_app *app;
        struct ust_app_channel *ua_chan;
        struct ust_app_session *ua_sess;
-       lttng::urcu::read_lock_guard rcu_lock;
-       auto signature = lttng::make_unique_wrapper<char, lttng::free>(raw_signature);
-       auto fields = lttng::make_unique_wrapper<lttng_ust_ctl_field, lttng::free>(raw_fields);
-       auto model_emf_uri = lttng::make_unique_wrapper<char, lttng::free>(raw_model_emf_uri);
+       const lttng::urcu::read_lock_guard rcu_lock;
+       auto signature = lttng::make_unique_wrapper<char, lttng::memory::free>(raw_signature);
+       auto fields =
+               lttng::make_unique_wrapper<lttng_ust_ctl_field, lttng::memory::free>(raw_fields);
+       auto model_emf_uri =
+               lttng::make_unique_wrapper<char, lttng::memory::free>(raw_model_emf_uri);
 
        /* Lookup application. If not found, there is a code flow error. */
        app = find_app_by_notify_sock(sock);
 
        /* Lookup application. If not found, there is a code flow error. */
        app = find_app_by_notify_sock(sock);
@@ -6684,7 +6594,7 @@ static int add_event_ust_registry(int sock,
        }
 
        {
        }
 
        {
-               auto locked_registry = get_locked_session_registry(ua_sess);
+               auto locked_registry = get_locked_session_registry(ua_sess->get_identifier());
                if (locked_registry) {
                        /*
                         * From this point on, this call acquires the ownership of the signature,
                if (locked_registry) {
                        /*
                         * From this point on, this call acquires the ownership of the signature,
@@ -6694,7 +6604,7 @@ static int add_event_ust_registry(int sock,
                        try {
                                auto& channel = locked_registry->channel(chan_reg_key);
 
                        try {
                                auto& channel = locked_registry->channel(chan_reg_key);
 
-                               /* event_id is set on success. */
+                               /* id is set on success. */
                                channel.add_event(
                                        sobjd,
                                        cobjd,
                                channel.add_event(
                                        sobjd,
                                        cobjd,
@@ -6756,7 +6666,7 @@ static int add_event_ust_registry(int sock,
                return ret;
        }
 
                return ret;
        }
 
-       DBG3("UST registry event %s with id %" PRId32 " added successfully", name, event_id);
+       DBG_FMT("UST registry event successfully added: name={}, id={}", name, event_id);
        return ret;
 }
 
        return ret;
 }
 
@@ -6778,9 +6688,10 @@ static int add_enum_ust_registry(int sock,
        struct ust_app *app;
        struct ust_app_session *ua_sess;
        uint64_t enum_id = -1ULL;
        struct ust_app *app;
        struct ust_app_session *ua_sess;
        uint64_t enum_id = -1ULL;
-       lttng::urcu::read_lock_guard read_lock_guard;
-       auto entries = lttng::make_unique_wrapper<struct lttng_ust_ctl_enum_entry, lttng::free>(
-               raw_entries);
+       const lttng::urcu::read_lock_guard read_lock_guard;
+       auto entries =
+               lttng::make_unique_wrapper<struct lttng_ust_ctl_enum_entry, lttng::memory::free>(
+                       raw_entries);
 
        /* Lookup application. If not found, there is a code flow error. */
        app = find_app_by_notify_sock(sock);
 
        /* Lookup application. If not found, there is a code flow error. */
        app = find_app_by_notify_sock(sock);
@@ -6798,7 +6709,7 @@ static int add_enum_ust_registry(int sock,
                return 0;
        }
 
                return 0;
        }
 
-       auto locked_registry = get_locked_session_registry(ua_sess);
+       auto locked_registry = get_locked_session_registry(ua_sess->get_identifier());
        if (!locked_registry) {
                DBG("Application session is being torn down (registry not found). Aborting enum registration.");
                return 0;
        if (!locked_registry) {
                DBG("Application session is being torn down (registry not found). Aborting enum registration.");
                return 0;
@@ -6816,7 +6727,7 @@ static int add_enum_ust_registry(int sock,
                application_reply_code = 0;
        } catch (const std::exception& ex) {
                ERR("%s: %s",
                application_reply_code = 0;
        } catch (const std::exception& ex) {
                ERR("%s: %s",
-                   fmt::format(
+                   lttng::format(
                            "Failed to create or find enumeration provided by application: app = {}, enumeration name = {}",
                            *app,
                            name)
                            "Failed to create or find enumeration provided by application: app = {}, enumeration name = {}",
                            *app,
                            name)
@@ -6887,6 +6798,7 @@ int ust_app_recv_notify(int sock)
                int sobjd, cobjd, loglevel_value;
                char name[LTTNG_UST_ABI_SYM_NAME_LEN], *sig, *model_emf_uri;
                size_t nr_fields;
                int sobjd, cobjd, loglevel_value;
                char name[LTTNG_UST_ABI_SYM_NAME_LEN], *sig, *model_emf_uri;
                size_t nr_fields;
+               uint64_t tracer_token = 0;
                struct lttng_ust_ctl_field *fields;
 
                DBG2("UST app ustctl register event received");
                struct lttng_ust_ctl_field *fields;
 
                DBG2("UST app ustctl register event received");
@@ -6899,7 +6811,8 @@ int ust_app_recv_notify(int sock)
                                                        &sig,
                                                        &nr_fields,
                                                        &fields,
                                                        &sig,
                                                        &nr_fields,
                                                        &fields,
-                                                       &model_emf_uri);
+                                                       &model_emf_uri,
+                                                       &tracer_token);
                if (ret < 0) {
                        if (ret == -EPIPE || ret == -LTTNG_UST_ERR_EXITING) {
                                DBG3("UST app recv event failed. Application died: sock = %d",
                if (ret < 0) {
                        if (ret == -EPIPE || ret == -LTTNG_UST_ERR_EXITING) {
                                DBG3("UST app recv event failed. Application died: sock = %d",
@@ -6914,7 +6827,7 @@ int ust_app_recv_notify(int sock)
                }
 
                {
                }
 
                {
-                       lttng::urcu::read_lock_guard rcu_lock;
+                       const lttng::urcu::read_lock_guard rcu_lock;
                        const struct ust_app *app = find_app_by_notify_sock(sock);
                        if (!app) {
                                DBG("Application socket %d is being torn down. Abort event notify",
                        const struct ust_app *app = find_app_by_notify_sock(sock);
                        if (!app) {
                                DBG("Application socket %d is being torn down. Abort event notify",
@@ -7022,6 +6935,13 @@ int ust_app_recv_notify(int sock)
 
                break;
        }
 
                break;
        }
+       case LTTNG_UST_CTL_NOTIFY_CMD_KEY:
+       {
+               DBG2("UST app ustctl register key received");
+               ret = -LTTNG_UST_ERR_NOSYS;
+               // TODO
+               goto error;
+       }
        default:
                /* Should NEVER happen. */
                abort();
        default:
                /* Should NEVER happen. */
                abort();
@@ -7049,7 +6969,7 @@ void ust_app_notify_sock_unregister(int sock)
 
        LTTNG_ASSERT(sock >= 0);
 
 
        LTTNG_ASSERT(sock >= 0);
 
-       rcu_read_lock();
+       const lttng::urcu::read_lock_guard read_lock;
 
        obj = zmalloc<ust_app_notify_sock_obj>();
        if (!obj) {
 
        obj = zmalloc<ust_app_notify_sock_obj>();
        if (!obj) {
@@ -7096,7 +7016,6 @@ void ust_app_notify_sock_unregister(int sock)
        (void) lttng_ht_del(ust_app_ht_by_notify_sock, &iter);
 
 close_socket:
        (void) lttng_ht_del(ust_app_ht_by_notify_sock, &iter);
 
 close_socket:
-       rcu_read_unlock();
 
        /*
         * Close socket after a grace period to avoid for the socket to be reused
 
        /*
         * Close socket after a grace period to avoid for the socket to be reused
@@ -7111,13 +7030,9 @@ close_socket:
 /*
  * Destroy a ust app data structure and free its memory.
  */
 /*
  * Destroy a ust app data structure and free its memory.
  */
-void ust_app_destroy(struct ust_app *app)
+static void ust_app_destroy(ust_app& app)
 {
 {
-       if (!app) {
-               return;
-       }
-
-       call_rcu(&app->pid_n.head, delete_ust_app_rcu);
+       call_rcu(&app.pid_n.head, delete_ust_app_rcu);
 }
 
 /*
 }
 
 /*
@@ -7132,22 +7047,19 @@ enum lttng_error_code ust_app_snapshot_record(const struct ltt_ust_session *uses
 {
        int ret = 0;
        enum lttng_error_code status = LTTNG_OK;
 {
        int ret = 0;
        enum lttng_error_code status = LTTNG_OK;
-       struct lttng_ht_iter iter;
-       struct ust_app *app;
        char *trace_path = nullptr;
 
        LTTNG_ASSERT(usess);
        LTTNG_ASSERT(output);
 
        char *trace_path = nullptr;
 
        LTTNG_ASSERT(usess);
        LTTNG_ASSERT(output);
 
-       rcu_read_lock();
-
        switch (usess->buffer_type) {
        case LTTNG_BUFFER_PER_UID:
        {
        switch (usess->buffer_type) {
        case LTTNG_BUFFER_PER_UID:
        {
-               struct buffer_reg_uid *reg;
+               const lttng::urcu::read_lock_guard read_lock;
 
 
-               cds_list_for_each_entry (reg, &usess->buffer_reg_uid_list, lnode) {
-                       struct buffer_reg_channel *buf_reg_chan;
+               for (auto *reg :
+                    lttng::urcu::list_iteration_adapter<buffer_reg_uid, &buffer_reg_uid::lnode>(
+                            usess->buffer_reg_uid_list)) {
                        struct consumer_socket *socket;
                        char pathname[PATH_MAX];
                        size_t consumer_path_offset = 0;
                        struct consumer_socket *socket;
                        char pathname[PATH_MAX];
                        size_t consumer_path_offset = 0;
@@ -7185,8 +7097,11 @@ enum lttng_error_code ust_app_snapshot_record(const struct ltt_ust_session *uses
                                goto error;
                        }
                        /* Add the UST default trace dir to path. */
                                goto error;
                        }
                        /* Add the UST default trace dir to path. */
-                       cds_lfht_for_each_entry (
-                               reg->registry->channels->ht, &iter.iter, buf_reg_chan, node.node) {
+                       for (auto *buf_reg_chan :
+                            lttng::urcu::lfht_iteration_adapter<buffer_reg_channel,
+                                                                decltype(buffer_reg_channel::node),
+                                                                &buffer_reg_channel::node>(
+                                    *reg->registry->channels->ht)) {
                                status =
                                        consumer_snapshot_channel(socket,
                                                                  buf_reg_chan->consumer_key,
                                status =
                                        consumer_snapshot_channel(socket,
                                                                  buf_reg_chan->consumer_key,
@@ -7208,20 +7123,23 @@ enum lttng_error_code ust_app_snapshot_record(const struct ltt_ust_session *uses
                                goto error;
                        }
                }
                                goto error;
                        }
                }
+
                break;
        }
        case LTTNG_BUFFER_PER_PID:
        {
                break;
        }
        case LTTNG_BUFFER_PER_PID:
        {
-               cds_lfht_for_each_entry (ust_app_ht->ht, &iter.iter, app, pid_n.node) {
+               /* Iterate on all apps. */
+               for (auto *app :
+                    lttng::urcu::lfht_iteration_adapter<ust_app,
+                                                        decltype(ust_app::pid_n),
+                                                        &ust_app::pid_n>(*ust_app_ht->ht)) {
                        struct consumer_socket *socket;
                        struct consumer_socket *socket;
-                       struct lttng_ht_iter chan_iter;
-                       struct ust_app_channel *ua_chan;
                        struct ust_app_session *ua_sess;
                        lsu::registry_session *registry;
                        char pathname[PATH_MAX];
                        size_t consumer_path_offset = 0;
 
                        struct ust_app_session *ua_sess;
                        lsu::registry_session *registry;
                        char pathname[PATH_MAX];
                        size_t consumer_path_offset = 0;
 
-                       ua_sess = lookup_session_by_app(usess, app);
+                       ua_sess = ust_app_lookup_app_session(usess, app);
                        if (!ua_sess) {
                                /* Session not associated with this app. */
                                continue;
                        if (!ua_sess) {
                                /* Session not associated with this app. */
                                continue;
@@ -7250,8 +7168,12 @@ enum lttng_error_code ust_app_snapshot_record(const struct ltt_ust_session *uses
                                status = LTTNG_ERR_INVALID;
                                goto error;
                        }
                                status = LTTNG_ERR_INVALID;
                                goto error;
                        }
-                       cds_lfht_for_each_entry (
-                               ua_sess->channels->ht, &chan_iter.iter, ua_chan, node.node) {
+
+                       for (auto *ua_chan :
+                            lttng::urcu::lfht_iteration_adapter<ust_app_channel,
+                                                                decltype(ust_app_channel::node),
+                                                                &ust_app_channel::node>(
+                                    *ua_sess->channels->ht)) {
                                status =
                                        consumer_snapshot_channel(socket,
                                                                  ua_chan->key,
                                status =
                                        consumer_snapshot_channel(socket,
                                                                  ua_chan->key,
@@ -7269,7 +7191,7 @@ enum lttng_error_code ust_app_snapshot_record(const struct ltt_ust_session *uses
                                }
                        }
 
                                }
                        }
 
-                       registry = get_session_registry(ua_sess);
+                       registry = ust_app_get_session_registry(ua_sess->get_identifier());
                        if (!registry) {
                                DBG("Application session is being torn down. Skip application.");
                                continue;
                        if (!registry) {
                                DBG("Application session is being torn down. Skip application.");
                                continue;
@@ -7298,7 +7220,6 @@ enum lttng_error_code ust_app_snapshot_record(const struct ltt_ust_session *uses
 
 error:
        free(trace_path);
 
 error:
        free(trace_path);
-       rcu_read_unlock();
        return status;
 }
 
        return status;
 }
 
@@ -7309,22 +7230,20 @@ uint64_t ust_app_get_size_one_more_packet_per_stream(const struct ltt_ust_sessio
                                                     uint64_t cur_nr_packets)
 {
        uint64_t tot_size = 0;
                                                     uint64_t cur_nr_packets)
 {
        uint64_t tot_size = 0;
-       struct ust_app *app;
-       struct lttng_ht_iter iter;
 
        LTTNG_ASSERT(usess);
 
        switch (usess->buffer_type) {
        case LTTNG_BUFFER_PER_UID:
        {
 
        LTTNG_ASSERT(usess);
 
        switch (usess->buffer_type) {
        case LTTNG_BUFFER_PER_UID:
        {
-               struct buffer_reg_uid *reg;
-
-               cds_list_for_each_entry (reg, &usess->buffer_reg_uid_list, lnode) {
-                       struct buffer_reg_channel *buf_reg_chan;
-
-                       rcu_read_lock();
-                       cds_lfht_for_each_entry (
-                               reg->registry->channels->ht, &iter.iter, buf_reg_chan, node.node) {
+               for (auto *reg :
+                    lttng::urcu::list_iteration_adapter<buffer_reg_uid, &buffer_reg_uid::lnode>(
+                            usess->buffer_reg_uid_list)) {
+                       for (auto *buf_reg_chan :
+                            lttng::urcu::lfht_iteration_adapter<buffer_reg_channel,
+                                                                decltype(buffer_reg_channel::node),
+                                                                &buffer_reg_channel::node>(
+                                    *reg->registry->channels->ht)) {
                                if (cur_nr_packets >= buf_reg_chan->num_subbuf) {
                                        /*
                                         * Don't take channel into account if we
                                if (cur_nr_packets >= buf_reg_chan->num_subbuf) {
                                        /*
                                         * Don't take channel into account if we
@@ -7334,26 +7253,27 @@ uint64_t ust_app_get_size_one_more_packet_per_stream(const struct ltt_ust_sessio
                                }
                                tot_size += buf_reg_chan->subbuf_size * buf_reg_chan->stream_count;
                        }
                                }
                                tot_size += buf_reg_chan->subbuf_size * buf_reg_chan->stream_count;
                        }
-                       rcu_read_unlock();
                }
                break;
        }
        case LTTNG_BUFFER_PER_PID:
        {
                }
                break;
        }
        case LTTNG_BUFFER_PER_PID:
        {
-               rcu_read_lock();
-               cds_lfht_for_each_entry (ust_app_ht->ht, &iter.iter, app, pid_n.node) {
-                       struct ust_app_channel *ua_chan;
-                       struct ust_app_session *ua_sess;
-                       struct lttng_ht_iter chan_iter;
-
-                       ua_sess = lookup_session_by_app(usess, app);
+               /* Iterate on all apps. */
+               for (auto *app :
+                    lttng::urcu::lfht_iteration_adapter<ust_app,
+                                                        decltype(ust_app::pid_n),
+                                                        &ust_app::pid_n>(*ust_app_ht->ht)) {
+                       const auto *ua_sess = ust_app_lookup_app_session(usess, app);
                        if (!ua_sess) {
                                /* Session not associated with this app. */
                                continue;
                        }
 
                        if (!ua_sess) {
                                /* Session not associated with this app. */
                                continue;
                        }
 
-                       cds_lfht_for_each_entry (
-                               ua_sess->channels->ht, &chan_iter.iter, ua_chan, node.node) {
+                       for (auto *ua_chan :
+                            lttng::urcu::lfht_iteration_adapter<ust_app_channel,
+                                                                decltype(ust_app_channel::node),
+                                                                &ust_app_channel::node>(
+                                    *ua_sess->channels->ht)) {
                                if (cur_nr_packets >= ua_chan->attr.num_subbuf) {
                                        /*
                                         * Don't take channel into account if we
                                if (cur_nr_packets >= ua_chan->attr.num_subbuf) {
                                        /*
                                         * Don't take channel into account if we
@@ -7364,7 +7284,6 @@ uint64_t ust_app_get_size_one_more_packet_per_stream(const struct ltt_ust_sessio
                                tot_size += ua_chan->attr.subbuf_size * ua_chan->streams.count;
                        }
                }
                                tot_size += ua_chan->attr.subbuf_size * ua_chan->streams.count;
                        }
                }
-               rcu_read_unlock();
                break;
        }
        default:
                break;
        }
        default:
@@ -7416,31 +7335,30 @@ int ust_app_pid_get_channel_runtime_stats(struct ltt_ust_session *usess,
                                          uint64_t *lost)
 {
        int ret = 0;
                                          uint64_t *lost)
 {
        int ret = 0;
-       struct lttng_ht_iter iter;
        struct lttng_ht_node_str *ua_chan_node;
        struct lttng_ht_node_str *ua_chan_node;
-       struct ust_app *app;
        struct ust_app_session *ua_sess;
        struct ust_app_channel *ua_chan;
 
        *discarded = 0;
        *lost = 0;
 
        struct ust_app_session *ua_sess;
        struct ust_app_channel *ua_chan;
 
        *discarded = 0;
        *lost = 0;
 
-       rcu_read_lock();
        /*
         * Iterate over every registered applications. Sum counters for
         * all applications containing requested session and channel.
         */
        /*
         * Iterate over every registered applications. Sum counters for
         * all applications containing requested session and channel.
         */
-       cds_lfht_for_each_entry (ust_app_ht->ht, &iter.iter, app, pid_n.node) {
+       for (auto *app :
+            lttng::urcu::lfht_iteration_adapter<ust_app, decltype(ust_app::pid_n), &ust_app::pid_n>(
+                    *ust_app_ht->ht)) {
                struct lttng_ht_iter uiter;
 
                struct lttng_ht_iter uiter;
 
-               ua_sess = lookup_session_by_app(usess, app);
+               ua_sess = ust_app_lookup_app_session(usess, app);
                if (ua_sess == nullptr) {
                        continue;
                }
 
                /* Get channel */
                lttng_ht_lookup(ua_sess->channels, (void *) uchan->name, &uiter);
                if (ua_sess == nullptr) {
                        continue;
                }
 
                /* Get channel */
                lttng_ht_lookup(ua_sess->channels, (void *) uchan->name, &uiter);
-               ua_chan_node = lttng_ht_iter_get_node_str(&uiter);
+               ua_chan_node = lttng_ht_iter_get_node<lttng_ht_node_str>(&uiter);
                /* If the session is found for the app, the channel must be there */
                LTTNG_ASSERT(ua_chan_node);
 
                /* If the session is found for the app, the channel must be there */
                LTTNG_ASSERT(ua_chan_node);
 
@@ -7466,7 +7384,6 @@ int ust_app_pid_get_channel_runtime_stats(struct ltt_ust_session *usess,
                }
        }
 
                }
        }
 
-       rcu_read_unlock();
        return ret;
 }
 
        return ret;
 }
 
@@ -7477,30 +7394,24 @@ static int ust_app_regenerate_statedump(struct ltt_ust_session *usess, struct us
 
        DBG("Regenerating the metadata for ust app pid %d", app->pid);
 
 
        DBG("Regenerating the metadata for ust app pid %d", app->pid);
 
-       rcu_read_lock();
+       const lttng::urcu::read_lock_guard read_lock;
+       const auto update_health_code_on_exit =
+               lttng::make_scope_exit([]() noexcept { health_code_update(); });
 
 
-       ua_sess = lookup_session_by_app(usess, app);
+       ua_sess = ust_app_lookup_app_session(usess, app);
        if (ua_sess == nullptr) {
                /* The session is in teardown process. Ignore and continue. */
        if (ua_sess == nullptr) {
                /* The session is in teardown process. Ignore and continue. */
-               goto end;
+               return 0;
        }
 
        }
 
-       pthread_mutex_lock(&ua_sess->lock);
-
-       if (ua_sess->deleted) {
-               goto end_unlock;
+       const auto locked_ua_sess = ua_sess->lock();
+       if (locked_ua_sess->deleted) {
+               return 0;
        }
 
        pthread_mutex_lock(&app->sock_lock);
        ret = lttng_ust_ctl_regenerate_statedump(app->sock, ua_sess->handle);
        pthread_mutex_unlock(&app->sock_lock);
        }
 
        pthread_mutex_lock(&app->sock_lock);
        ret = lttng_ust_ctl_regenerate_statedump(app->sock, ua_sess->handle);
        pthread_mutex_unlock(&app->sock_lock);
-
-end_unlock:
-       pthread_mutex_unlock(&ua_sess->lock);
-
-end:
-       rcu_read_unlock();
-       health_code_update();
        return ret;
 }
 
        return ret;
 }
 
@@ -7509,28 +7420,19 @@ end:
  */
 int ust_app_regenerate_statedump_all(struct ltt_ust_session *usess)
 {
  */
 int ust_app_regenerate_statedump_all(struct ltt_ust_session *usess)
 {
-       int ret = 0;
-       struct lttng_ht_iter iter;
-       struct ust_app *app;
-
        DBG("Regenerating the metadata for all UST apps");
 
        DBG("Regenerating the metadata for all UST apps");
 
-       rcu_read_lock();
-
-       cds_lfht_for_each_entry (ust_app_ht->ht, &iter.iter, app, pid_n.node) {
+       /* Iterate on all apps. */
+       for (auto *app :
+            lttng::urcu::lfht_iteration_adapter<ust_app, decltype(ust_app::pid_n), &ust_app::pid_n>(
+                    *ust_app_ht->ht)) {
                if (!app->compatible) {
                        continue;
                }
 
                if (!app->compatible) {
                        continue;
                }
 
-               ret = ust_app_regenerate_statedump(usess, app);
-               if (ret < 0) {
-                       /* Continue to the next app even on error */
-                       continue;
-               }
+               (void) ust_app_regenerate_statedump(usess, app);
        }
 
        }
 
-       rcu_read_unlock();
-
        return 0;
 }
 
        return 0;
 }
 
@@ -7539,26 +7441,22 @@ int ust_app_regenerate_statedump_all(struct ltt_ust_session *usess)
  *
  * Return LTTNG_OK on success or else an LTTng error code.
  */
  *
  * Return LTTNG_OK on success or else an LTTng error code.
  */
-enum lttng_error_code ust_app_rotate_session(struct ltt_session *session)
+enum lttng_error_code ust_app_rotate_session(const ltt_session::locked_ref& session)
 {
        int ret;
        enum lttng_error_code cmd_ret = LTTNG_OK;
 {
        int ret;
        enum lttng_error_code cmd_ret = LTTNG_OK;
-       struct lttng_ht_iter iter;
-       struct ust_app *app;
        struct ltt_ust_session *usess = session->ust_session;
 
        LTTNG_ASSERT(usess);
 
        struct ltt_ust_session *usess = session->ust_session;
 
        LTTNG_ASSERT(usess);
 
-       rcu_read_lock();
-
        switch (usess->buffer_type) {
        case LTTNG_BUFFER_PER_UID:
        {
        switch (usess->buffer_type) {
        case LTTNG_BUFFER_PER_UID:
        {
-               struct buffer_reg_uid *reg;
-
-               cds_list_for_each_entry (reg, &usess->buffer_reg_uid_list, lnode) {
-                       struct buffer_reg_channel *buf_reg_chan;
+               for (auto *reg :
+                    lttng::urcu::list_iteration_adapter<buffer_reg_uid, &buffer_reg_uid::lnode>(
+                            usess->buffer_reg_uid_list)) {
                        struct consumer_socket *socket;
                        struct consumer_socket *socket;
+                       const lttng::urcu::read_lock_guard read_lock;
 
                        /* Get consumer socket to use to push the metadata.*/
                        socket = consumer_find_socket_by_bitness(reg->bits_per_long,
 
                        /* Get consumer socket to use to push the metadata.*/
                        socket = consumer_find_socket_by_bitness(reg->bits_per_long,
@@ -7569,8 +7467,11 @@ enum lttng_error_code ust_app_rotate_session(struct ltt_session *session)
                        }
 
                        /* Rotate the data channels. */
                        }
 
                        /* Rotate the data channels. */
-                       cds_lfht_for_each_entry (
-                               reg->registry->channels->ht, &iter.iter, buf_reg_chan, node.node) {
+                       for (auto *buf_reg_chan :
+                            lttng::urcu::lfht_iteration_adapter<buffer_reg_channel,
+                                                                decltype(buffer_reg_channel::node),
+                                                                &buffer_reg_channel::node>(
+                                    *reg->registry->channels->ht)) {
                                ret = consumer_rotate_channel(socket,
                                                              buf_reg_chan->consumer_key,
                                                              usess->consumer,
                                ret = consumer_rotate_channel(socket,
                                                              buf_reg_chan->consumer_key,
                                                              usess->consumer,
@@ -7612,14 +7513,27 @@ enum lttng_error_code ust_app_rotate_session(struct ltt_session *session)
        }
        case LTTNG_BUFFER_PER_PID:
        {
        }
        case LTTNG_BUFFER_PER_PID:
        {
-               cds_lfht_for_each_entry (ust_app_ht->ht, &iter.iter, app, pid_n.node) {
+               /* Iterate on all apps. */
+               for (auto raw_app :
+                    lttng::urcu::lfht_iteration_adapter<ust_app,
+                                                        decltype(ust_app::pid_n),
+                                                        &ust_app::pid_n>(*ust_app_ht->ht)) {
                        struct consumer_socket *socket;
                        struct consumer_socket *socket;
-                       struct lttng_ht_iter chan_iter;
-                       struct ust_app_channel *ua_chan;
                        struct ust_app_session *ua_sess;
                        lsu::registry_session *registry;
                        struct ust_app_session *ua_sess;
                        lsu::registry_session *registry;
+                       bool app_reference_taken;
 
 
-                       ua_sess = lookup_session_by_app(usess, app);
+                       app_reference_taken = ust_app_get(*raw_app);
+                       if (!app_reference_taken) {
+                               /* Application unregistered concurrently, skip it. */
+                               DBG("Could not get application reference as it is being torn down; skipping application");
+                               continue;
+                       }
+
+                       ust_app_reference app(raw_app);
+                       raw_app = nullptr;
+
+                       ua_sess = ust_app_lookup_app_session(usess, app.get());
                        if (!ua_sess) {
                                /* Session not associated with this app. */
                                continue;
                        if (!ua_sess) {
                                /* Session not associated with this app. */
                                continue;
@@ -7633,23 +7547,20 @@ enum lttng_error_code ust_app_rotate_session(struct ltt_session *session)
                                goto error;
                        }
 
                                goto error;
                        }
 
-                       registry = get_session_registry(ua_sess);
-                       if (!registry) {
-                               DBG("Application session is being torn down. Skip application.");
-                               continue;
-                       }
+                       registry = ust_app_get_session_registry(ua_sess->get_identifier());
+                       LTTNG_ASSERT(registry);
 
                        /* Rotate the data channels. */
 
                        /* Rotate the data channels. */
-                       cds_lfht_for_each_entry (
-                               ua_sess->channels->ht, &chan_iter.iter, ua_chan, node.node) {
+                       for (auto *ua_chan :
+                            lttng::urcu::lfht_iteration_adapter<ust_app_channel,
+                                                                decltype(ust_app_channel::node),
+                                                                &ust_app_channel::node>(
+                                    *ua_sess->channels->ht)) {
                                ret = consumer_rotate_channel(socket,
                                                              ua_chan->key,
                                                              ua_sess->consumer,
                                                              /* is_metadata_channel */ false);
                                if (ret < 0) {
                                ret = consumer_rotate_channel(socket,
                                                              ua_chan->key,
                                                              ua_sess->consumer,
                                                              /* is_metadata_channel */ false);
                                if (ret < 0) {
-                                       /* Per-PID buffer and application going away. */
-                                       if (ret == -LTTNG_ERR_CHAN_NOT_FOUND)
-                                               continue;
                                        cmd_ret = LTTNG_ERR_ROTATION_FAIL_CONSUMER;
                                        goto error;
                                }
                                        cmd_ret = LTTNG_ERR_ROTATION_FAIL_CONSUMER;
                                        goto error;
                                }
@@ -7661,18 +7572,17 @@ enum lttng_error_code ust_app_rotate_session(struct ltt_session *session)
 
                                (void) push_metadata(locked_registry, usess->consumer);
                        }
 
                                (void) push_metadata(locked_registry, usess->consumer);
                        }
+
                        ret = consumer_rotate_channel(socket,
                                                      registry->_metadata_key,
                                                      ua_sess->consumer,
                                                      /* is_metadata_channel */ true);
                        if (ret < 0) {
                        ret = consumer_rotate_channel(socket,
                                                      registry->_metadata_key,
                                                      ua_sess->consumer,
                                                      /* is_metadata_channel */ true);
                        if (ret < 0) {
-                               /* Per-PID buffer and application going away. */
-                               if (ret == -LTTNG_ERR_CHAN_NOT_FOUND)
-                                       continue;
                                cmd_ret = LTTNG_ERR_ROTATION_FAIL_CONSUMER;
                                goto error;
                        }
                }
                                cmd_ret = LTTNG_ERR_ROTATION_FAIL_CONSUMER;
                                goto error;
                        }
                }
+
                break;
        }
        default:
                break;
        }
        default:
@@ -7683,27 +7593,26 @@ enum lttng_error_code ust_app_rotate_session(struct ltt_session *session)
        cmd_ret = LTTNG_OK;
 
 error:
        cmd_ret = LTTNG_OK;
 
 error:
-       rcu_read_unlock();
        return cmd_ret;
 }
 
 enum lttng_error_code ust_app_create_channel_subdirectories(const struct ltt_ust_session *usess)
 {
        enum lttng_error_code ret = LTTNG_OK;
        return cmd_ret;
 }
 
 enum lttng_error_code ust_app_create_channel_subdirectories(const struct ltt_ust_session *usess)
 {
        enum lttng_error_code ret = LTTNG_OK;
-       struct lttng_ht_iter iter;
        enum lttng_trace_chunk_status chunk_status;
        char *pathname_index;
        int fmt_ret;
 
        LTTNG_ASSERT(usess->current_trace_chunk);
        enum lttng_trace_chunk_status chunk_status;
        char *pathname_index;
        int fmt_ret;
 
        LTTNG_ASSERT(usess->current_trace_chunk);
-       rcu_read_lock();
 
        switch (usess->buffer_type) {
        case LTTNG_BUFFER_PER_UID:
        {
 
        switch (usess->buffer_type) {
        case LTTNG_BUFFER_PER_UID:
        {
-               struct buffer_reg_uid *reg;
+               const lttng::urcu::read_lock_guard read_lock;
 
 
-               cds_list_for_each_entry (reg, &usess->buffer_reg_uid_list, lnode) {
+               for (auto *reg :
+                    lttng::urcu::list_iteration_adapter<buffer_reg_uid, &buffer_reg_uid::lnode>(
+                            usess->buffer_reg_uid_list)) {
                        fmt_ret = asprintf(&pathname_index,
                                           DEFAULT_UST_TRACE_DIR "/" DEFAULT_UST_TRACE_UID_PATH
                                                                 "/" DEFAULT_INDEX_DIR,
                        fmt_ret = asprintf(&pathname_index,
                                           DEFAULT_UST_TRACE_DIR "/" DEFAULT_UST_TRACE_UID_PATH
                                                                 "/" DEFAULT_INDEX_DIR,
@@ -7731,8 +7640,6 @@ enum lttng_error_code ust_app_create_channel_subdirectories(const struct ltt_ust
        }
        case LTTNG_BUFFER_PER_PID:
        {
        }
        case LTTNG_BUFFER_PER_PID:
        {
-               struct ust_app *app;
-
                /*
                 * Create the toplevel ust/ directory in case no apps are running.
                 */
                /*
                 * Create the toplevel ust/ directory in case no apps are running.
                 */
@@ -7743,17 +7650,19 @@ enum lttng_error_code ust_app_create_channel_subdirectories(const struct ltt_ust
                        goto error;
                }
 
                        goto error;
                }
 
-               cds_lfht_for_each_entry (ust_app_ht->ht, &iter.iter, app, pid_n.node) {
-                       struct ust_app_session *ua_sess;
-                       lsu::registry_session *registry;
-
-                       ua_sess = lookup_session_by_app(usess, app);
+               /* Iterate on all apps. */
+               for (auto *app :
+                    lttng::urcu::lfht_iteration_adapter<ust_app,
+                                                        decltype(ust_app::pid_n),
+                                                        &ust_app::pid_n>(*ust_app_ht->ht)) {
+                       const auto ua_sess = ust_app_lookup_app_session(usess, app);
                        if (!ua_sess) {
                                /* Session not associated with this app. */
                                continue;
                        }
 
                        if (!ua_sess) {
                                /* Session not associated with this app. */
                                continue;
                        }
 
-                       registry = get_session_registry(ua_sess);
+                       const auto registry =
+                               ust_app_get_session_registry(ua_sess->get_identifier());
                        if (!registry) {
                                DBG("Application session is being torn down. Skip application.");
                                continue;
                        if (!registry) {
                                DBG("Application session is being torn down. Skip application.");
                                continue;
@@ -7787,7 +7696,6 @@ enum lttng_error_code ust_app_create_channel_subdirectories(const struct ltt_ust
 
        ret = LTTNG_OK;
 error:
 
        ret = LTTNG_OK;
 error:
-       rcu_read_unlock();
        return ret;
 }
 
        return ret;
 }
 
@@ -7796,151 +7704,48 @@ error:
  *
  * Return LTTNG_OK on success or else an LTTng error code.
  */
  *
  * Return LTTNG_OK on success or else an LTTng error code.
  */
-enum lttng_error_code ust_app_clear_session(struct ltt_session *session)
+enum lttng_error_code ust_app_clear_session(const ltt_session::locked_ref& session)
 {
 {
-       int ret;
-       enum lttng_error_code cmd_ret = LTTNG_OK;
-       struct lttng_ht_iter iter;
-       struct ust_app *app;
-       struct ltt_ust_session *usess = session->ust_session;
-
-       LTTNG_ASSERT(usess);
-
-       rcu_read_lock();
+       const ltt_ust_session& usess = *session->ust_session;
 
 
-       if (usess->active) {
+       if (usess.active) {
                ERR("Expecting inactive session %s (%" PRIu64 ")", session->name, session->id);
                ERR("Expecting inactive session %s (%" PRIu64 ")", session->name, session->id);
-               cmd_ret = LTTNG_ERR_FATAL;
-               goto end;
+               return LTTNG_ERR_FATAL;
        }
 
        }
 
-       switch (usess->buffer_type) {
-       case LTTNG_BUFFER_PER_UID:
-       {
-               struct buffer_reg_uid *reg;
-
-               cds_list_for_each_entry (reg, &usess->buffer_reg_uid_list, lnode) {
-                       struct buffer_reg_channel *buf_reg_chan;
-                       struct consumer_socket *socket;
-
-                       /* Get consumer socket to use to push the metadata.*/
-                       socket = consumer_find_socket_by_bitness(reg->bits_per_long,
-                                                                usess->consumer);
-                       if (!socket) {
-                               cmd_ret = LTTNG_ERR_INVALID;
-                               goto error_socket;
-                       }
-
-                       /* Clear the data channels. */
-                       cds_lfht_for_each_entry (
-                               reg->registry->channels->ht, &iter.iter, buf_reg_chan, node.node) {
-                               ret = consumer_clear_channel(socket, buf_reg_chan->consumer_key);
-                               if (ret < 0) {
-                                       goto error;
-                               }
-                       }
+       const auto channel_keys = session->user_space_consumer_channel_keys();
+       for (auto it = channel_keys.begin(); it != channel_keys.end(); ++it) {
+               const auto key = *it;
 
 
-                       {
-                               auto locked_registry = reg->registry->reg.ust->lock();
-                               (void) push_metadata(locked_registry, usess->consumer);
-                       }
+               const auto consumer_socket = consumer_find_socket_by_bitness(
+                       key.bitness ==
+                                       lttng::sessiond::user_space_consumer_channel_keys::
+                                               consumer_bitness::ABI_32 ?
+                               32 :
+                               64,
+                       usess.consumer);
 
 
-                       /*
-                        * Clear the metadata channel.
-                        * Metadata channel is not cleared per se but we still need to
-                        * perform a rotation operation on it behind the scene.
-                        */
-                       ret = consumer_clear_channel(socket, reg->registry->reg.ust->_metadata_key);
-                       if (ret < 0) {
-                               goto error;
-                       }
+               if (key.type ==
+                   lttng::sessiond::user_space_consumer_channel_keys::channel_type::METADATA) {
+                       (void) push_metadata(it.get_registry_session()->lock(), usess.consumer);
                }
                }
-               break;
-       }
-       case LTTNG_BUFFER_PER_PID:
-       {
-               cds_lfht_for_each_entry (ust_app_ht->ht, &iter.iter, app, pid_n.node) {
-                       struct consumer_socket *socket;
-                       struct lttng_ht_iter chan_iter;
-                       struct ust_app_channel *ua_chan;
-                       struct ust_app_session *ua_sess;
-                       lsu::registry_session *registry;
-
-                       ua_sess = lookup_session_by_app(usess, app);
-                       if (!ua_sess) {
-                               /* Session not associated with this app. */
-                               continue;
-                       }
-
-                       /* Get the right consumer socket for the application. */
-                       socket = consumer_find_socket_by_bitness(app->abi.bits_per_long,
-                                                                usess->consumer);
-                       if (!socket) {
-                               cmd_ret = LTTNG_ERR_INVALID;
-                               goto error_socket;
-                       }
 
 
-                       registry = get_session_registry(ua_sess);
-                       if (!registry) {
-                               DBG("Application session is being torn down. Skip application.");
+               const auto clean_ret = consumer_clear_channel(consumer_socket, key.key_value);
+               if (clean_ret < 0) {
+                       if (clean_ret == -LTTCOMM_CONSUMERD_CHAN_NOT_FOUND &&
+                           usess.buffer_type == LTTNG_BUFFER_PER_PID) {
                                continue;
                        }
 
                                continue;
                        }
 
-                       /* Clear the data channels. */
-                       cds_lfht_for_each_entry (
-                               ua_sess->channels->ht, &chan_iter.iter, ua_chan, node.node) {
-                               ret = consumer_clear_channel(socket, ua_chan->key);
-                               if (ret < 0) {
-                                       /* Per-PID buffer and application going away. */
-                                       if (ret == -LTTNG_ERR_CHAN_NOT_FOUND) {
-                                               continue;
-                                       }
-                                       goto error;
-                               }
+                       if (clean_ret == -LTTCOMM_CONSUMERD_RELAYD_CLEAR_DISALLOWED) {
+                               return LTTNG_ERR_CLEAR_RELAY_DISALLOWED;
                        }
 
                        }
 
-                       {
-                               auto locked_registry = registry->lock();
-                               (void) push_metadata(locked_registry, usess->consumer);
-                       }
-
-                       /*
-                        * Clear the metadata channel.
-                        * Metadata channel is not cleared per se but we still need to
-                        * perform rotation operation on it behind the scene.
-                        */
-                       ret = consumer_clear_channel(socket, registry->_metadata_key);
-                       if (ret < 0) {
-                               /* Per-PID buffer and application going away. */
-                               if (ret == -LTTNG_ERR_CHAN_NOT_FOUND) {
-                                       continue;
-                               }
-                               goto error;
-                       }
+                       return LTTNG_ERR_CLEAR_FAIL_CONSUMER;
                }
                }
-               break;
-       }
-       default:
-               abort();
-               break;
-       }
-
-       cmd_ret = LTTNG_OK;
-       goto end;
-
-error:
-       switch (-ret) {
-       case LTTCOMM_CONSUMERD_RELAYD_CLEAR_DISALLOWED:
-               cmd_ret = LTTNG_ERR_CLEAR_RELAY_DISALLOWED;
-               break;
-       default:
-               cmd_ret = LTTNG_ERR_CLEAR_FAIL_CONSUMER;
        }
 
        }
 
-error_socket:
-end:
-       rcu_read_unlock();
-       return cmd_ret;
+       return LTTNG_OK;
 }
 
 /*
 }
 
 /*
@@ -7959,105 +7764,37 @@ end:
  * daemon as the same "offset" in a metadata stream will no longer point
  * to the same content.
  */
  * daemon as the same "offset" in a metadata stream will no longer point
  * to the same content.
  */
-enum lttng_error_code ust_app_open_packets(struct ltt_session *session)
+enum lttng_error_code ust_app_open_packets(const ltt_session::locked_ref& session)
 {
 {
-       enum lttng_error_code ret = LTTNG_OK;
-       struct lttng_ht_iter iter;
-       struct ltt_ust_session *usess = session->ust_session;
+       const ltt_ust_session& usess = *session->ust_session;
 
 
-       LTTNG_ASSERT(usess);
-
-       rcu_read_lock();
-
-       switch (usess->buffer_type) {
-       case LTTNG_BUFFER_PER_UID:
-       {
-               struct buffer_reg_uid *reg;
-
-               cds_list_for_each_entry (reg, &usess->buffer_reg_uid_list, lnode) {
-                       struct buffer_reg_channel *buf_reg_chan;
-                       struct consumer_socket *socket;
-
-                       socket = consumer_find_socket_by_bitness(reg->bits_per_long,
-                                                                usess->consumer);
-                       if (!socket) {
-                               ret = LTTNG_ERR_FATAL;
-                               goto error;
-                       }
-
-                       cds_lfht_for_each_entry (
-                               reg->registry->channels->ht, &iter.iter, buf_reg_chan, node.node) {
-                               const int open_ret = consumer_open_channel_packets(
-                                       socket, buf_reg_chan->consumer_key);
-
-                               if (open_ret < 0) {
-                                       ret = LTTNG_ERR_UNK;
-                                       goto error;
-                               }
-                       }
+       for (const auto key : session->user_space_consumer_channel_keys()) {
+               if (key.type !=
+                   lttng::sessiond::user_space_consumer_channel_keys::channel_type::DATA) {
+                       continue;
                }
                }
-               break;
-       }
-       case LTTNG_BUFFER_PER_PID:
-       {
-               struct ust_app *app;
 
 
-               cds_lfht_for_each_entry (ust_app_ht->ht, &iter.iter, app, pid_n.node) {
-                       struct consumer_socket *socket;
-                       struct lttng_ht_iter chan_iter;
-                       struct ust_app_channel *ua_chan;
-                       struct ust_app_session *ua_sess;
-                       lsu::registry_session *registry;
+               const auto socket = consumer_find_socket_by_bitness(
+                       key.bitness ==
+                                       lttng::sessiond::user_space_consumer_channel_keys::
+                                               consumer_bitness::ABI_32 ?
+                               32 :
+                               64,
+                       usess.consumer);
 
 
-                       ua_sess = lookup_session_by_app(usess, app);
-                       if (!ua_sess) {
-                               /* Session not associated with this app. */
+               const auto open_ret = consumer_open_channel_packets(socket, key.key_value);
+               if (open_ret < 0) {
+                       /* Per-PID buffer and application going away. */
+                       if (open_ret == -LTTCOMM_CONSUMERD_CHAN_NOT_FOUND &&
+                           usess.buffer_type == LTTNG_BUFFER_PER_PID) {
                                continue;
                        }
 
                                continue;
                        }
 
-                       /* Get the right consumer socket for the application. */
-                       socket = consumer_find_socket_by_bitness(app->abi.bits_per_long,
-                                                                usess->consumer);
-                       if (!socket) {
-                               ret = LTTNG_ERR_FATAL;
-                               goto error;
-                       }
-
-                       registry = get_session_registry(ua_sess);
-                       if (!registry) {
-                               DBG("Application session is being torn down. Skip application.");
-                               continue;
-                       }
-
-                       cds_lfht_for_each_entry (
-                               ua_sess->channels->ht, &chan_iter.iter, ua_chan, node.node) {
-                               const int open_ret =
-                                       consumer_open_channel_packets(socket, ua_chan->key);
-
-                               if (open_ret < 0) {
-                                       /*
-                                        * Per-PID buffer and application going
-                                        * away.
-                                        */
-                                       if (open_ret == -LTTNG_ERR_CHAN_NOT_FOUND) {
-                                               continue;
-                                       }
-
-                                       ret = LTTNG_ERR_UNK;
-                                       goto error;
-                               }
-                       }
+                       return LTTNG_ERR_UNK;
                }
                }
-               break;
-       }
-       default:
-               abort();
-               break;
        }
 
        }
 
-error:
-       rcu_read_unlock();
-       return ret;
+       return LTTNG_OK;
 }
 
 lsu::ctl_field_quirks ust_app::ctl_field_quirks() const
 }
 
 lsu::ctl_field_quirks ust_app::ctl_field_quirks() const
@@ -8085,4 +7822,31 @@ lsu::ctl_field_quirks ust_app::ctl_field_quirks() const
         */
        return v_major <= 9 ? lsu::ctl_field_quirks::UNDERSCORE_PREFIXED_VARIANT_TAG_MAPPINGS :
                              lsu::ctl_field_quirks::NONE;
         */
        return v_major <= 9 ? lsu::ctl_field_quirks::UNDERSCORE_PREFIXED_VARIANT_TAG_MAPPINGS :
                              lsu::ctl_field_quirks::NONE;
-}
\ No newline at end of file
+}
+
+static void ust_app_release(urcu_ref *ref)
+{
+       auto& app = *lttng::utils::container_of(ref, &ust_app::ref);
+
+       ust_app_unregister(app);
+       ust_app_destroy(app);
+}
+
+bool ust_app_get(ust_app& app)
+{
+       return urcu_ref_get_unless_zero(&app.ref);
+}
+
+void ust_app_put(struct ust_app *app)
+{
+       if (!app) {
+               return;
+       }
+
+       urcu_ref_put(&app->ref, ust_app_release);
+}
+
+lttng_ht *ust_app_get_all()
+{
+       return ust_app_ht;
+}
This page took 0.079051 seconds and 4 git commands to generate.