Clean-up: modernize pretty_xml.cpp
[lttng-tools.git] / src / bin / lttng-sessiond / ust-app.cpp
index 122bbddaf02fe99289c44207ff2bff657faec784..12250edfdaefb1341736ba5b78c62a53ceba1c8e 100644 (file)
@@ -19,7 +19,6 @@
 #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"
@@ -33,6 +32,7 @@
 #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>
 
@@ -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;
 
-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;
@@ -87,7 +87,7 @@ namespace {
  */
 static lsu::registry_session *get_session_registry(const struct ust_app_session *ua_sess)
 {
-       lsu::registry_session *registry = NULL;
+       lsu::registry_session *registry = nullptr;
 
        LTTNG_ASSERT(ua_sess);
 
@@ -135,7 +135,7 @@ lsu::registry_session::locked_ptr get_locked_session_registry(const struct ust_a
 /*
  * Return the incremented value of next_channel_key.
  */
-static uint64_t get_next_channel_key(void)
+static uint64_t get_next_channel_key()
 {
        uint64_t ret;
 
@@ -148,7 +148,7 @@ static uint64_t get_next_channel_key(void)
 /*
  * Return the atomically incremented value of next_session_id.
  */
-static uint64_t get_next_session_id(void)
+static uint64_t get_next_session_id()
 {
        uint64_t ret;
 
@@ -181,14 +181,12 @@ 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);
 
        event = caa_container_of(node, struct ust_app_event, node.node);
        key = (ust_app_ht_key *) _key;
-       ev_loglevel_value = event->attr.loglevel;
 
        /* Match the 4 elements of the key: name, filter, loglevel, exclusions */
 
@@ -198,18 +196,12 @@ static int ht_match_ust_app_event(struct cds_lfht_node *node, const void *_key)
        }
 
        /* 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. */
@@ -264,7 +256,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;
-       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,
@@ -331,6 +324,12 @@ static void delete_ust_app_ctx(int sock, struct ust_app_ctx *ua_ctx, struct ust_
                }
                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);
 }
 
@@ -346,9 +345,9 @@ static void delete_ust_app_event(int sock, struct ust_app_event *ua_event, struc
        ASSERT_RCU_READ_LOCKED();
 
        free(ua_event->filter);
-       if (ua_event->exclusion != NULL)
+       if (ua_event->exclusion != nullptr)
                free(ua_event->exclusion);
-       if (ua_event->obj != NULL) {
+       if (ua_event->obj != nullptr) {
                pthread_mutex_lock(&app->sock_lock);
                ret = lttng_ust_ctl_release_object(sock, ua_event->obj);
                pthread_mutex_unlock(&app->sock_lock);
@@ -395,11 +394,11 @@ static void delete_ust_app_event_notifier_rule(
 
        LTTNG_ASSERT(ua_event_notifier_rule);
 
-       if (ua_event_notifier_rule->exclusion != NULL) {
+       if (ua_event_notifier_rule->exclusion != nullptr) {
                free(ua_event_notifier_rule->exclusion);
        }
 
-       if (ua_event_notifier_rule->obj != NULL) {
+       if (ua_event_notifier_rule->obj != nullptr) {
                pthread_mutex_lock(&app->sock_lock);
                ret = lttng_ust_ctl_release_object(sock, ua_event_notifier_rule->obj);
                pthread_mutex_unlock(&app->sock_lock);
@@ -505,7 +504,7 @@ static void save_per_pid_lost_discarded_counters(struct ust_app_channel *ua_chan
                return;
        }
 
-       rcu_read_lock();
+       lttng::urcu::read_lock_guard read_lock;
        session = session_find_by_id(ua_chan->session->tracing_id);
        if (!session || !session->ust_session) {
                /*
@@ -548,7 +547,6 @@ static void save_per_pid_lost_discarded_counters(struct ust_app_channel *ua_chan
        uchan->per_pid_closed_app_lost += lost;
 
 end:
-       rcu_read_unlock();
        if (session) {
                session_put(session);
        }
@@ -617,7 +615,7 @@ static void delete_ust_app_channel(int sock,
                }
        }
 
-       if (ua_chan->obj != NULL) {
+       if (ua_chan->obj != nullptr) {
                /* Remove channel from application UST object descriptor. */
                iter.iter.node = &ua_chan->ust_objd_node.node;
                ret = lttng_ht_del(app->ust_objd, &iter);
@@ -694,7 +692,7 @@ ssize_t ust_app_push_metadata(const lsu::registry_session::locked_ptr& locked_re
                              int send_zero_data)
 {
        int ret;
-       char *metadata_str = NULL;
+       char *metadata_str = nullptr;
        size_t len, offset, new_metadata_len_sent;
        ssize_t ret_val;
        uint64_t metadata_key, metadata_version;
@@ -1034,24 +1032,24 @@ static void delete_ust_app(struct ust_app *app)
        /* 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();
+               lttng::urcu::read_lock_guard read_lock;
                delete_ust_app_session(sock, ua_sess, app);
-               rcu_read_unlock();
        }
 
        /* 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);
+       {
+               lttng::urcu::read_lock_guard read_lock;
 
-               delete_ust_app_event_notifier_rule(app->sock, event_notifier_rule, app);
-       }
+               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);
 
-       rcu_read_unlock();
+                       delete_ust_app_event_notifier_rule(app->sock, event_notifier_rule, app);
+               }
+       }
 
        lttng_ht_destroy(app->sessions);
        lttng_ht_destroy(app->ust_sessions_objd);
@@ -1163,13 +1161,13 @@ end:
 /*
  * Alloc new UST app session.
  */
-static struct ust_app_session *alloc_ust_app_session(void)
+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 */
        ua_sess = zmalloc<ust_app_session>();
-       if (ua_sess == NULL) {
+       if (ua_sess == nullptr) {
                PERROR("malloc");
                goto error_free;
        }
@@ -1177,12 +1175,12 @@ static struct ust_app_session *alloc_ust_app_session(void)
        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, NULL);
+       pthread_mutex_init(&ua_sess->lock, nullptr);
 
        return ua_sess;
 
 error_free:
-       return NULL;
+       return nullptr;
 }
 
 /*
@@ -1196,7 +1194,7 @@ static struct ust_app_channel *alloc_ust_app_channel(const char *name,
 
        /* Init most of the default value by allocating and zeroing */
        ua_chan = zmalloc<ust_app_channel>();
-       if (ua_chan == NULL) {
+       if (ua_chan == nullptr) {
                PERROR("malloc");
                goto error;
        }
@@ -1205,7 +1203,7 @@ 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';
 
-       ua_chan->enabled = 1;
+       ua_chan->enabled = true;
        ua_chan->handle = -1;
        ua_chan->session = ua_sess;
        ua_chan->key = get_next_channel_key();
@@ -1235,7 +1233,7 @@ static struct ust_app_channel *alloc_ust_app_channel(const char *name,
        return ua_chan;
 
 error:
-       return NULL;
+       return nullptr;
 }
 
 /*
@@ -1243,12 +1241,12 @@ error:
  *
  * Return newly allocated stream pointer or NULL on error.
  */
-struct ust_app_stream *ust_app_alloc_stream(void)
+struct ust_app_stream *ust_app_alloc_stream()
 {
-       struct ust_app_stream *stream = NULL;
+       struct ust_app_stream *stream = nullptr;
 
        stream = zmalloc<ust_app_stream>();
-       if (stream == NULL) {
+       if (stream == nullptr) {
                PERROR("zmalloc ust app stream");
                goto error;
        }
@@ -1269,12 +1267,12 @@ static struct ust_app_event *alloc_ust_app_event(char *name, struct lttng_ust_ab
 
        /* Init most of the default value by allocating and zeroing */
        ua_event = zmalloc<ust_app_event>();
-       if (ua_event == NULL) {
+       if (ua_event == nullptr) {
                PERROR("Failed to allocate ust_app_event structure");
                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);
@@ -1289,7 +1287,7 @@ static struct ust_app_event *alloc_ust_app_event(char *name, struct lttng_ust_ab
        return ua_event;
 
 error:
-       return NULL;
+       return nullptr;
 }
 
 /*
@@ -1301,16 +1299,16 @@ alloc_ust_app_event_notifier_rule(struct lttng_trigger *trigger)
        enum lttng_event_rule_generate_exclusions_status generate_exclusion_status;
        enum lttng_condition_status cond_status;
        struct ust_app_event_notifier_rule *ua_event_notifier_rule;
-       struct lttng_condition *condition = NULL;
-       const struct lttng_event_rule *event_rule = NULL;
+       struct lttng_condition *condition = nullptr;
+       const struct lttng_event_rule *event_rule = nullptr;
 
        ua_event_notifier_rule = zmalloc<ust_app_event_notifier_rule>();
-       if (ua_event_notifier_rule == NULL) {
+       if (ua_event_notifier_rule == nullptr) {
                PERROR("Failed to allocate ust_app_event_notifier_rule structure");
                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);
 
@@ -1351,7 +1349,7 @@ error_put_trigger:
        lttng_trigger_put(trigger);
 error:
        free(ua_event_notifier_rule);
-       return NULL;
+       return nullptr;
 }
 
 /*
@@ -1362,7 +1360,7 @@ static struct ust_app_ctx *alloc_ust_app_ctx(struct lttng_ust_context_attr *uctx
        struct ust_app_ctx *ua_ctx;
 
        ua_ctx = zmalloc<ust_app_ctx>();
-       if (ua_ctx == NULL) {
+       if (ua_ctx == nullptr) {
                goto error;
        }
 
@@ -1371,7 +1369,7 @@ static struct ust_app_ctx *alloc_ust_app_ctx(struct lttng_ust_context_attr *uctx
        if (uctx) {
                memcpy(&ua_ctx->ctx, uctx, sizeof(ua_ctx->ctx));
                if (uctx->ctx == LTTNG_UST_ABI_CONTEXT_APP_CONTEXT) {
-                       char *provider_name = NULL, *ctx_name = NULL;
+                       char *provider_name = nullptr, *ctx_name = nullptr;
 
                        provider_name = strdup(uctx->u.app_ctx.provider_name);
                        ctx_name = strdup(uctx->u.app_ctx.ctx_name);
@@ -1390,7 +1388,7 @@ static struct ust_app_ctx *alloc_ust_app_ctx(struct lttng_ust_context_attr *uctx
        return ua_ctx;
 error:
        free(ua_ctx);
-       return NULL;
+       return nullptr;
 }
 
 /*
@@ -1401,7 +1399,7 @@ error:
 static struct lttng_ust_abi_filter_bytecode *
 create_ust_filter_bytecode_from_bytecode(const struct lttng_bytecode *orig_f)
 {
-       struct lttng_ust_abi_filter_bytecode *filter = NULL;
+       struct lttng_ust_abi_filter_bytecode *filter = nullptr;
 
        /* Copy filter bytecode. */
        filter = zmalloc<lttng_ust_abi_filter_bytecode>(sizeof(*filter) + orig_f->len);
@@ -1426,7 +1424,7 @@ error:
 static struct lttng_ust_abi_capture_bytecode *
 create_ust_capture_bytecode_from_bytecode(const struct lttng_bytecode *orig_f)
 {
-       struct lttng_ust_abi_capture_bytecode *capture = NULL;
+       struct lttng_ust_abi_capture_bytecode *capture = nullptr;
 
        /* Copy capture bytecode. */
        capture = zmalloc<lttng_ust_abi_capture_bytecode>(sizeof(*capture) + orig_f->len);
@@ -1457,7 +1455,7 @@ struct ust_app *ust_app_find_by_sock(int sock)
 
        lttng_ht_lookup(ust_app_ht_by_sock, (void *) ((unsigned long) sock), &iter);
        node = lttng_ht_iter_get_node_ulong(&iter);
-       if (node == NULL) {
+       if (node == nullptr) {
                DBG2("UST app find by sock %d not found", sock);
                goto error;
        }
@@ -1465,7 +1463,7 @@ struct ust_app *ust_app_find_by_sock(int sock)
        return lttng::utils::container_of(node, &ust_app::sock_n);
 
 error:
-       return NULL;
+       return nullptr;
 }
 
 /*
@@ -1481,7 +1479,7 @@ static struct ust_app *find_app_by_notify_sock(int sock)
 
        lttng_ht_lookup(ust_app_ht_by_notify_sock, (void *) ((unsigned long) sock), &iter);
        node = lttng_ht_iter_get_node_ulong(&iter);
-       if (node == NULL) {
+       if (node == nullptr) {
                DBG2("UST app find by notify sock %d not found", sock);
                goto error;
        }
@@ -1489,7 +1487,7 @@ static struct ust_app *find_app_by_notify_sock(int sock)
        return lttng::utils::container_of(node, &ust_app::notify_sock_n);
 
 error:
-       return NULL;
+       return nullptr;
 }
 
 /*
@@ -1501,12 +1499,13 @@ error:
 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)
 {
        struct lttng_ht_iter iter;
        struct lttng_ht_node_str *node;
-       struct ust_app_event *event = NULL;
+       struct ust_app_event *event = nullptr;
        struct ust_app_ht_key key;
 
        LTTNG_ASSERT(name);
@@ -1515,7 +1514,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;
-       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;
 
@@ -1526,7 +1526,7 @@ static struct ust_app_event *find_ust_app_event(struct lttng_ht *ht,
                        &key,
                        &iter.iter);
        node = lttng_ht_iter_get_node_str(&iter);
-       if (node == NULL) {
+       if (node == nullptr) {
                goto end;
        }
 
@@ -1547,14 +1547,14 @@ static struct ust_app_event_notifier_rule *find_ust_app_event_notifier_rule(stru
 {
        struct lttng_ht_iter iter;
        struct lttng_ht_node_u64 *node;
-       struct ust_app_event_notifier_rule *event_notifier_rule = NULL;
+       struct ust_app_event_notifier_rule *event_notifier_rule = nullptr;
 
        LTTNG_ASSERT(ht);
        ASSERT_RCU_READ_LOCKED();
 
        lttng_ht_lookup(ht, &token, &iter);
        node = lttng_ht_iter_get_node_u64(&iter);
-       if (node == NULL) {
+       if (node == nullptr) {
                DBG2("UST app event notifier rule token not found: token = %" PRIu64, token);
                goto end;
        }
@@ -1619,7 +1619,7 @@ static int set_ust_object_filter(struct ust_app *app,
                                 struct lttng_ust_abi_object_data *ust_object)
 {
        int ret;
-       struct lttng_ust_abi_filter_bytecode *ust_bytecode = NULL;
+       struct lttng_ust_abi_filter_bytecode *ust_bytecode = nullptr;
 
        health_code_update();
 
@@ -1671,7 +1671,7 @@ static int set_ust_capture(struct ust_app *app,
                           struct lttng_ust_abi_object_data *ust_object)
 {
        int ret;
-       struct lttng_ust_abi_capture_bytecode *ust_bytecode = NULL;
+       struct lttng_ust_abi_capture_bytecode *ust_bytecode = nullptr;
 
        health_code_update();
 
@@ -1721,7 +1721,7 @@ error:
 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 = NULL;
+       struct lttng_ust_abi_event_exclusion *ust_exclusion = nullptr;
        size_t exclusion_alloc_size = sizeof(struct lttng_ust_abi_event_exclusion) +
                LTTNG_UST_ABI_SYM_NAME_LEN * exclusion->count;
 
@@ -1746,7 +1746,7 @@ static int set_ust_object_exclusions(struct ust_app *app,
                                     struct lttng_ust_abi_object_data *ust_object)
 {
        int ret;
-       struct lttng_ust_abi_event_exclusion *ust_exclusions = NULL;
+       struct lttng_ust_abi_event_exclusion *ust_exclusions = nullptr;
 
        LTTNG_ASSERT(exclusions && exclusions->count > 0);
 
@@ -1910,7 +1910,7 @@ static int enable_ust_channel(struct ust_app *app,
                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);
 
@@ -2212,9 +2212,9 @@ static int create_ust_event_notifier(struct ust_app *app,
 {
        int ret = 0;
        enum lttng_condition_status condition_status;
-       const struct lttng_condition *condition = NULL;
+       const struct lttng_condition *condition = nullptr;
        struct lttng_ust_abi_event_notifier event_notifier;
-       const struct lttng_event_rule *event_rule = NULL;
+       const struct lttng_event_rule *event_rule = nullptr;
        unsigned int capture_bytecode_count = 0, i;
        enum lttng_condition_status cond_status;
        enum lttng_event_rule_type event_rule_type;
@@ -2373,7 +2373,7 @@ static void shadow_copy_event(struct ust_app_event *ua_event, struct ltt_ust_eve
                exclusion_alloc_size = sizeof(struct lttng_event_exclusion) +
                        LTTNG_UST_ABI_SYM_NAME_LEN * uevent->exclusion->count;
                ua_event->exclusion = zmalloc<lttng_event_exclusion>(exclusion_alloc_size);
-               if (ua_event->exclusion == NULL) {
+               if (ua_event->exclusion == nullptr) {
                        PERROR("malloc");
                } else {
                        memcpy(ua_event->exclusion, uevent->exclusion, exclusion_alloc_size);
@@ -2539,14 +2539,14 @@ static struct ust_app_session *lookup_session_by_app(const struct ltt_ust_sessio
 
        __lookup_session_by_app(usess, app, &iter);
        node = lttng_ht_iter_get_node_u64(&iter);
-       if (node == NULL) {
+       if (node == nullptr) {
                goto error;
        }
 
        return lttng::utils::container_of(node, &ust_app_session::node);
 
 error:
-       return NULL;
+       return nullptr;
 }
 
 /*
@@ -2566,7 +2566,7 @@ static int setup_buffer_reg_pid(struct ust_app_session *ua_sess,
        LTTNG_ASSERT(ua_sess);
        LTTNG_ASSERT(app);
 
-       rcu_read_lock();
+       lttng::urcu::read_lock_guard read_lock;
 
        reg_pid = buffer_reg_pid_find(ua_sess->id);
        if (!reg_pid) {
@@ -2614,7 +2614,6 @@ end:
                *regp = reg_pid;
        }
 error:
-       rcu_read_unlock();
        return ret;
 }
 
@@ -2636,7 +2635,7 @@ static int setup_buffer_reg_uid(struct ltt_ust_session *usess,
        LTTNG_ASSERT(usess);
        LTTNG_ASSERT(app);
 
-       rcu_read_lock();
+       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) {
@@ -2675,7 +2674,7 @@ static int setup_buffer_reg_uid(struct ltt_ust_session *usess,
                 * that if the buffer registry can be found, its ust registry is
                 * non-NULL.
                 */
-               buffer_reg_uid_destroy(reg_uid, NULL);
+               buffer_reg_uid_destroy(reg_uid, nullptr);
                goto error;
        }
 
@@ -2690,7 +2689,6 @@ end:
                *regp = reg_uid;
        }
 error:
-       rcu_read_unlock();
        return ret;
 }
 
@@ -2720,12 +2718,12 @@ static int find_or_create_ust_app_session(struct ltt_ust_session *usess,
        health_code_update();
 
        ua_sess = lookup_session_by_app(usess, app);
-       if (ua_sess == NULL) {
+       if (ua_sess == nullptr) {
                DBG2("UST app pid: %d session id %" PRIu64 " not found, creating it",
                     app->pid,
                     usess->id);
                ua_sess = alloc_ust_app_session();
-               if (ua_sess == NULL) {
+               if (ua_sess == nullptr) {
                        /* Only malloc can failed so something is really wrong */
                        ret = -ENOMEM;
                        goto error;
@@ -2737,7 +2735,7 @@ static int find_or_create_ust_app_session(struct ltt_ust_session *usess,
        switch (usess->buffer_type) {
        case LTTNG_BUFFER_PER_PID:
                /* Init local registry. */
-               ret = setup_buffer_reg_pid(ua_sess, app, NULL);
+               ret = setup_buffer_reg_pid(ua_sess, app, nullptr);
                if (ret < 0) {
                        delete_ust_app_session(-1, ua_sess, app);
                        goto error;
@@ -2745,7 +2743,7 @@ static int find_or_create_ust_app_session(struct ltt_ust_session *usess,
                break;
        case LTTNG_BUFFER_PER_UID:
                /* Look for a global registry. If none exists, create one. */
-               ret = setup_buffer_reg_uid(usess, ua_sess, app, NULL);
+               ret = setup_buffer_reg_uid(usess, ua_sess, app, nullptr);
                if (ret < 0) {
                        delete_ust_app_session(-1, ua_sess, app);
                        goto error;
@@ -2841,13 +2839,13 @@ static int ht_match_ust_app_ctx(struct cds_lfht_node *node, const void *_key)
        case LTTNG_UST_ABI_CONTEXT_PERF_THREAD_COUNTER:
                if (strncmp(key->u.perf_counter.name,
                            ctx->ctx.u.perf_counter.name,
-                           sizeof(key->u.perf_counter.name))) {
+                           sizeof(key->u.perf_counter.name)) != 0) {
                        goto no_match;
                }
                break;
        case LTTNG_UST_ABI_CONTEXT_APP_CONTEXT:
-               if (strcmp(key->u.app_ctx.provider_name, ctx->ctx.u.app_ctx.provider_name) ||
-                   strcmp(key->u.app_ctx.ctx_name, ctx->ctx.u.app_ctx.ctx_name)) {
+               if (strcmp(key->u.app_ctx.provider_name, ctx->ctx.u.app_ctx.provider_name) != 0 ||
+                   strcmp(key->u.app_ctx.ctx_name, ctx->ctx.u.app_ctx.ctx_name) != 0) {
                        goto no_match;
                }
                break;
@@ -2873,7 +2871,7 @@ static struct ust_app_ctx *find_ust_app_context(struct lttng_ht *ht,
 {
        struct lttng_ht_iter iter;
        struct lttng_ht_node_ulong *node;
-       struct ust_app_ctx *app_ctx = NULL;
+       struct ust_app_ctx *app_ctx = nullptr;
 
        LTTNG_ASSERT(uctx);
        LTTNG_ASSERT(ht);
@@ -2919,7 +2917,7 @@ static int create_ust_app_channel_context(struct ust_app_channel *ua_chan,
        }
 
        ua_ctx = alloc_ust_app_ctx(uctx);
-       if (ua_ctx == NULL) {
+       if (ua_ctx == nullptr) {
                /* malloc failed */
                ret = -ENOMEM;
                goto error;
@@ -2952,7 +2950,7 @@ static int enable_ust_app_event(struct ust_app_event *ua_event, struct ust_app *
                goto error;
        }
 
-       ua_event->enabled = 1;
+       ua_event->enabled = true;
 
 error:
        return ret;
@@ -2970,7 +2968,7 @@ static int disable_ust_app_event(struct ust_app_event *ua_event, struct ust_app
                goto error;
        }
 
-       ua_event->enabled = 0;
+       ua_event->enabled = false;
 
 error:
        return ret;
@@ -2990,7 +2988,7 @@ static int disable_ust_app_channel(struct ust_app_session *ua_sess,
                goto error;
        }
 
-       ua_chan->enabled = 0;
+       ua_chan->enabled = false;
 
 error:
        return ret;
@@ -3013,7 +3011,7 @@ static int enable_ust_app_channel(struct ust_app_session *ua_sess,
 
        lttng_ht_lookup(ua_sess->channels, (void *) uchan->name, &iter);
        ua_chan_node = lttng_ht_iter_get_node_str(&iter);
-       if (ua_chan_node == NULL) {
+       if (ua_chan_node == nullptr) {
                DBG2("Unable to find channel %s in ust session id %" PRIu64,
                     uchan->name,
                     ua_sess->tracing_id);
@@ -3053,7 +3051,7 @@ static int do_consumer_create_channel(struct ltt_ust_session *usess,
        LTTNG_ASSERT(ua_chan);
        LTTNG_ASSERT(registry);
 
-       rcu_read_lock();
+       lttng::urcu::read_lock_guard read_lock;
        health_code_update();
 
        /* Get the right consumer socket for the application. */
@@ -3108,7 +3106,6 @@ static int do_consumer_create_channel(struct ltt_ust_session *usess,
                }
        }
 
-       rcu_read_unlock();
        return 0;
 
 error_destroy:
@@ -3125,7 +3122,6 @@ error_ask:
        lttng_fd_put(LTTNG_FD_APPS, 1);
 error:
        health_code_update();
-       rcu_read_unlock();
        return ret;
 }
 
@@ -3238,7 +3234,7 @@ static int setup_buffer_reg_streams(struct buffer_reg_channel *buf_reg_chan,
                 * stream call does not release the object.
                 */
                reg_stream->obj.ust = stream->obj;
-               stream->obj = NULL;
+               stream->obj = nullptr;
                buffer_reg_stream_add(reg_stream, buf_reg_chan);
 
                /* We don't need the streams anymore. */
@@ -3263,7 +3259,7 @@ static int create_buffer_reg_channel(struct buffer_reg_session *reg_sess,
                                     struct buffer_reg_channel **regp)
 {
        int ret;
-       struct buffer_reg_channel *buf_reg_chan = NULL;
+       struct buffer_reg_channel *buf_reg_chan = nullptr;
 
        LTTNG_ASSERT(reg_sess);
        LTTNG_ASSERT(ua_chan);
@@ -3332,7 +3328,7 @@ static int setup_buffer_reg_channel(struct buffer_reg_session *reg_sess,
        }
 
        buf_reg_chan->obj.ust = ua_chan->obj;
-       ua_chan->obj = NULL;
+       ua_chan->obj = nullptr;
 
        return 0;
 
@@ -3448,7 +3444,7 @@ 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;
-       struct ltt_session *session = NULL;
+       struct ltt_session *session = nullptr;
        enum lttng_error_code notification_ret;
 
        LTTNG_ASSERT(app);
@@ -3571,7 +3567,7 @@ static int create_channel_per_pid(struct ust_app *app,
        int ret;
        lsu::registry_session *registry;
        enum lttng_error_code cmd_ret;
-       struct ltt_session *session = NULL;
+       struct ltt_session *session = nullptr;
        uint64_t chan_reg_key;
 
        LTTNG_ASSERT(app);
@@ -3581,7 +3577,7 @@ static int create_channel_per_pid(struct ust_app *app,
 
        DBG("UST app creating channel %s with per PID buffers", ua_chan->name);
 
-       rcu_read_lock();
+       lttng::urcu::read_lock_guard read_lock;
 
        registry = get_session_registry(ua_sess);
        /* The UST app session lock is held, registry shall not be null. */
@@ -3649,7 +3645,6 @@ error_remove_from_registry:
                }
        }
 error:
-       rcu_read_unlock();
        if (session) {
                session_put(session);
        }
@@ -3743,13 +3738,13 @@ 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);
        ua_chan_node = lttng_ht_iter_get_node_str(&iter);
-       if (ua_chan_node != NULL) {
+       if (ua_chan_node != nullptr) {
                ua_chan = lttng::utils::container_of(ua_chan_node, &ust_app_channel::node);
                goto end;
        }
 
        ua_chan = alloc_ust_app_channel(uchan->name, ua_sess, &uchan->attr);
-       if (ua_chan == NULL) {
+       if (ua_chan == nullptr) {
                /* Only malloc can fail here */
                ret = -ENOMEM;
                goto error;
@@ -3789,7 +3784,7 @@ static int create_ust_app_event(struct ust_app_channel *ua_chan,
        ASSERT_RCU_READ_LOCKED();
 
        ua_event = alloc_ust_app_event(uevent->attr.name, &uevent->attr);
-       if (ua_event == NULL) {
+       if (ua_event == nullptr) {
                /* Only failure mode of alloc_ust_app_event(). */
                ret = -ENOMEM;
                goto end;
@@ -3844,7 +3839,7 @@ static int create_ust_app_event_notifier_rule(struct lttng_trigger *trigger, str
        ASSERT_RCU_READ_LOCKED();
 
        ua_event_notifier_rule = alloc_ust_app_event_notifier_rule(trigger);
-       if (ua_event_notifier_rule == NULL) {
+       if (ua_event_notifier_rule == nullptr) {
                ret = -ENOMEM;
                goto end;
        }
@@ -3899,7 +3894,7 @@ static int create_ust_app_metadata(struct ust_app_session *ua_sess,
        int ret = 0;
        struct ust_app_channel *metadata;
        struct consumer_socket *socket;
-       struct ltt_session *session = NULL;
+       struct ltt_session *session = nullptr;
 
        LTTNG_ASSERT(ua_sess);
        LTTNG_ASSERT(app);
@@ -3917,7 +3912,7 @@ static int create_ust_app_metadata(struct ust_app_session *ua_sess,
        }
 
        /* Allocate UST metadata */
-       metadata = alloc_ust_app_channel(DEFAULT_METADATA_NAME, ua_sess, NULL);
+       metadata = alloc_ust_app_channel(DEFAULT_METADATA_NAME, ua_sess, nullptr);
        if (!metadata) {
                /* malloc() failed */
                ret = -ENOMEM;
@@ -4002,13 +3997,13 @@ error:
  */
 struct ust_app *ust_app_find_by_pid(pid_t pid)
 {
-       struct ust_app *app = NULL;
+       struct ust_app *app = nullptr;
        struct lttng_ht_node_ulong *node;
        struct lttng_ht_iter iter;
 
        lttng_ht_lookup(ust_app_ht, (void *) ((unsigned long) pid), &iter);
        node = lttng_ht_iter_get_node_ulong(&iter);
-       if (node == NULL) {
+       if (node == nullptr) {
                DBG2("UST app no found with pid %d", pid);
                goto error;
        }
@@ -4031,8 +4026,8 @@ error:
 struct ust_app *ust_app_create(struct ust_register_msg *msg, int sock)
 {
        int ret;
-       struct ust_app *lta = NULL;
-       struct lttng_pipe *event_notifier_event_source_pipe = NULL;
+       struct ust_app *lta = nullptr;
+       struct lttng_pipe *event_notifier_event_source_pipe = nullptr;
 
        LTTNG_ASSERT(msg);
        LTTNG_ASSERT(sock >= 0);
@@ -4071,11 +4066,13 @@ struct ust_app *ust_app_create(struct ust_register_msg *msg, int sock)
        }
 
        lta = zmalloc<ust_app>();
-       if (lta == NULL) {
+       if (lta == nullptr) {
                PERROR("malloc");
                goto error_free_pipe;
        }
 
+       urcu_ref_init(&lta->ref);
+
        lta->event_notifier_group.event_pipe = event_notifier_event_source_pipe;
 
        lta->ppid = msg->ppid;
@@ -4116,7 +4113,7 @@ struct ust_app *ust_app_create(struct ust_register_msg *msg, int sock)
        lta->pid = msg->pid;
        lttng_ht_node_init_ulong(&lta->pid_n, (unsigned long) lta->pid);
        lta->sock = sock;
-       pthread_mutex_init(&lta->sock_lock, NULL);
+       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);
@@ -4126,7 +4123,7 @@ error_free_pipe:
        lttng_pipe_destroy(event_notifier_event_source_pipe);
        lttng_fd_put(LTTNG_FD_APPS, 2);
 error:
-       return NULL;
+       return nullptr;
 }
 
 /*
@@ -4137,9 +4134,9 @@ void ust_app_add(struct ust_app *app)
        LTTNG_ASSERT(app);
        LTTNG_ASSERT(app->notify_sock >= 0);
 
-       app->registration_time = time(NULL);
+       app->registration_time = time(nullptr);
 
-       rcu_read_lock();
+       lttng::urcu::read_lock_guard read_lock;
 
        /*
         * On a re-registration, we want to kick out the previous registration of
@@ -4169,8 +4166,6 @@ void ust_app_add(struct ust_app *app)
            app->notify_sock,
            app->v_major,
            app->v_minor);
-
-       rcu_read_unlock();
 }
 
 /*
@@ -4228,7 +4223,7 @@ int ust_app_setup_event_notifier_group(struct ust_app *app)
 {
        int ret;
        int event_pipe_write_fd;
-       struct lttng_ust_abi_object_data *event_notifier_group = NULL;
+       struct lttng_ust_abi_object_data *event_notifier_group = nullptr;
        enum lttng_error_code lttng_ret;
        enum event_notifier_error_accounting_status event_notifier_error_accounting_status;
 
@@ -4331,34 +4326,16 @@ error_accounting:
 error:
        lttng_ust_ctl_release_object(app->sock, app->event_notifier_group.object);
        free(app->event_notifier_group.object);
-       app->event_notifier_group.object = NULL;
+       app->event_notifier_group.object = nullptr;
        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);
+       lttng::urcu::read_lock_guard read_lock;
 
        /*
         * For per-PID buffers, perform "push metadata" and flush all
@@ -4366,25 +4343,24 @@ void ust_app_unregister(int sock)
         * 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) {
+       cds_lfht_for_each_entry (app.sessions->ht, &iter.iter, ua_sess, node.node) {
+               const auto del_ret = lttng_ht_del(app.sessions, &iter);
+               if (del_ret) {
                        /* 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.
                 */
-               pthread_mutex_lock(&ua_sess->lock);
+               lttng::pthread::lock_guard ust_app_session_lock(ua_sess->lock);
 
                if (ua_sess->deleted) {
-                       pthread_mutex_unlock(&ua_sess->lock);
                        continue;
                }
 
@@ -4427,22 +4403,17 @@ void ust_app_unregister(int sock)
                                locked_registry.reset();
                        }
                }
-               cds_list_add(&ua_sess->teardown_node, &lta->teardown_head);
 
-               pthread_mutex_unlock(&ua_sess->lock);
+               cds_list_add(&ua_sess->teardown_node, &app.teardown_head);
        }
 
-       /* 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.
         */
-       iter.iter.node = &lta->notify_sock_n.node;
+       iter.iter.node = &app.notify_sock_n.node;
        (void) lttng_ht_del(ust_app_ht_by_notify_sock, &iter);
 
        /*
@@ -4450,17 +4421,47 @@ void ust_app_unregister(int sock)
         * 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);
+       iter.iter.node = &app.pid_n.node;
+       if (lttng_ht_del(ust_app_ht, &iter)) {
+               DBG3("Unregister app by PID %d failed. This can happen on pid reuse", app.pid);
        }
+}
 
-       /* Free memory */
-       call_rcu(&lta->pid_n.head, delete_ust_app_rcu);
+/*
+ * 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 ust_app *app;
+       struct lttng_ht_node_ulong *node;
+       struct lttng_ht_iter ust_app_sock_iter;
+       int ret;
 
-       rcu_read_unlock();
-       return;
+       lttng::urcu::read_lock_guard read_lock;
+
+       /* 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_ulong(&ust_app_sock_iter);
+       assert(node);
+
+       app = caa_container_of(node, struct ust_app, sock_n);
+
+       DBG_FMT("Application unregistering after socket activity: pid={}, socket_fd={}",
+               app->pid,
+               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);
 }
 
 /*
@@ -4476,81 +4477,55 @@ int ust_app_list_events(struct lttng_event **events)
 
        nbmem = UST_APP_EVENT_LIST_SIZE;
        tmp_event = calloc<lttng_event>(nbmem);
-       if (tmp_event == NULL) {
+       if (tmp_event == nullptr) {
                PERROR("zmalloc ust app events");
                ret = -ENOMEM;
                goto error;
        }
 
-       rcu_read_lock();
+       {
+               lttng::urcu::read_lock_guard read_lock;
 
-       cds_lfht_for_each_entry (ust_app_ht->ht, &iter.iter, app, pid_n.node) {
-               struct lttng_ust_abi_tracepoint_iter uiter;
+               cds_lfht_for_each_entry (ust_app_ht->ht, &iter.iter, app, pid_n.node) {
+                       struct lttng_ust_abi_tracepoint_iter uiter;
 
-               health_code_update();
+                       health_code_update();
 
-               if (!app->compatible) {
-                       /*
-                        * TODO: In time, we should notice the caller of this error by
-                        * telling him that this is a version error.
-                        */
-                       continue;
-               }
-               pthread_mutex_lock(&app->sock_lock);
-               handle = lttng_ust_ctl_tracepoint_list(app->sock);
-               if (handle < 0) {
-                       if (handle != -EPIPE && handle != -LTTNG_UST_ERR_EXITING) {
-                               ERR("UST app list events getting handle failed for app pid %d",
-                                   app->pid);
+                       if (!app->compatible) {
+                               /*
+                                * TODO: In time, we should notice the caller of this error by
+                                * telling him that this is a version error.
+                                */
+                               continue;
                        }
-                       pthread_mutex_unlock(&app->sock_lock);
-                       continue;
-               }
 
-               while ((ret = lttng_ust_ctl_tracepoint_list_get(app->sock, handle, &uiter)) !=
-                      -LTTNG_UST_ERR_NOENT) {
-                       /* Handle ustctl error. */
-                       if (ret < 0) {
-                               int release_ret;
-
-                               if (ret != -LTTNG_UST_ERR_EXITING && ret != -EPIPE) {
-                                       ERR("UST app tp list get failed for app %d with ret %d",
-                                           app->sock,
-                                           ret);
-                               } else {
-                                       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 &&
-                                   release_ret != -EPIPE) {
-                                       ERR("Error releasing app handle for app %d with ret %d",
-                                           app->sock,
-                                           release_ret);
+                       pthread_mutex_lock(&app->sock_lock);
+                       handle = lttng_ust_ctl_tracepoint_list(app->sock);
+                       if (handle < 0) {
+                               if (handle != -EPIPE && handle != -LTTNG_UST_ERR_EXITING) {
+                                       ERR("UST app list events getting handle failed for app pid %d",
+                                           app->pid);
                                }
                                pthread_mutex_unlock(&app->sock_lock);
-                               goto rcu_error;
+                               continue;
                        }
 
-                       health_code_update();
-                       if (count >= nbmem) {
-                               /* In case the realloc fails, we free the memory */
-                               struct lttng_event *new_tmp_event;
-                               size_t new_nbmem;
-
-                               new_nbmem = nbmem << 1;
-                               DBG2("Reallocating event list from %zu to %zu entries",
-                                    nbmem,
-                                    new_nbmem);
-                               new_tmp_event = (lttng_event *) realloc(
-                                       tmp_event, new_nbmem * sizeof(struct lttng_event));
-                               if (new_tmp_event == NULL) {
+                       while ((ret = lttng_ust_ctl_tracepoint_list_get(
+                                       app->sock, handle, &uiter)) != -LTTNG_UST_ERR_NOENT) {
+                               /* Handle ustctl error. */
+                               if (ret < 0) {
                                        int release_ret;
 
-                                       PERROR("realloc ust app events");
+                                       if (ret != -LTTNG_UST_ERR_EXITING && ret != -EPIPE) {
+                                               ERR("UST app tp list get failed for app %d with ret %d",
+                                                   app->sock,
+                                                   ret);
+                                       } else {
+                                               DBG3("UST app tp list get failed. Application is dead");
+                                               break;
+                                       }
+
                                        free(tmp_event);
-                                       ret = -ENOMEM;
                                        release_ret =
                                                lttng_ust_ctl_release_handle(app->sock, handle);
                                        if (release_ret < 0 &&
@@ -4560,39 +4535,78 @@ int ust_app_list_events(struct lttng_event **events)
                                                    app->sock,
                                                    release_ret);
                                        }
+
                                        pthread_mutex_unlock(&app->sock_lock);
                                        goto rcu_error;
                                }
-                               /* Zero the new memory */
-                               memset(new_tmp_event + nbmem,
-                                      0,
-                                      (new_nbmem - nbmem) * sizeof(struct lttng_event));
-                               nbmem = new_nbmem;
-                               tmp_event = new_tmp_event;
+
+                               health_code_update();
+                               if (count >= nbmem) {
+                                       /* In case the realloc fails, we free the memory */
+                                       struct lttng_event *new_tmp_event;
+                                       size_t new_nbmem;
+
+                                       new_nbmem = nbmem << 1;
+                                       DBG2("Reallocating event list from %zu to %zu entries",
+                                            nbmem,
+                                            new_nbmem);
+                                       new_tmp_event = (lttng_event *) realloc(
+                                               tmp_event, new_nbmem * sizeof(struct lttng_event));
+                                       if (new_tmp_event == nullptr) {
+                                               int release_ret;
+
+                                               PERROR("realloc ust app events");
+                                               free(tmp_event);
+                                               ret = -ENOMEM;
+                                               release_ret = lttng_ust_ctl_release_handle(
+                                                       app->sock, handle);
+                                               if (release_ret < 0 &&
+                                                   release_ret != -LTTNG_UST_ERR_EXITING &&
+                                                   release_ret != -EPIPE) {
+                                                       ERR("Error releasing app handle for app %d with ret %d",
+                                                           app->sock,
+                                                           release_ret);
+                                               }
+
+                                               pthread_mutex_unlock(&app->sock_lock);
+                                               goto rcu_error;
+                                       }
+                                       /* Zero the new memory */
+                                       memset(new_tmp_event + nbmem,
+                                              0,
+                                              (new_nbmem - nbmem) * sizeof(struct lttng_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;
+                               tmp_event[count].pid = app->pid;
+                               tmp_event[count].enabled = -1;
+                               count++;
                        }
-                       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;
-                       tmp_event[count].pid = app->pid;
-                       tmp_event[count].enabled = -1;
-                       count++;
-               }
-               ret = lttng_ust_ctl_release_handle(app->sock, handle);
-               pthread_mutex_unlock(&app->sock_lock);
-               if (ret < 0) {
-                       if (ret == -EPIPE || ret == -LTTNG_UST_ERR_EXITING) {
-                               DBG3("Error releasing app handle. Application died: pid = %d, sock = %d",
-                                    app->pid,
-                                    app->sock);
-                       } else if (ret == -EAGAIN) {
-                               WARN("Error releasing app handle. Communication time out: pid = %d, sock = %d",
-                                    app->pid,
-                                    app->sock);
-                       } else {
-                               ERR("Error releasing app handle with ret %d: pid = %d, sock = %d",
-                                   ret,
-                                   app->pid,
-                                   app->sock);
+
+                       ret = lttng_ust_ctl_release_handle(app->sock, handle);
+                       pthread_mutex_unlock(&app->sock_lock);
+                       if (ret < 0) {
+                               if (ret == -EPIPE || ret == -LTTNG_UST_ERR_EXITING) {
+                                       DBG3("Error releasing app handle. Application died: pid = %d, sock = %d",
+                                            app->pid,
+                                            app->sock);
+                               } else if (ret == -EAGAIN) {
+                                       WARN("Error releasing app handle. Communication time out: pid = %d, sock = %d",
+                                            app->pid,
+                                            app->sock);
+                               } else {
+                                       ERR("Error releasing app handle with ret %d: pid = %d, sock = %d",
+                                           ret,
+                                           app->pid,
+                                           app->sock);
+                               }
                        }
                }
        }
@@ -4603,7 +4617,6 @@ int ust_app_list_events(struct lttng_event **events)
        DBG2("UST app list events done (%zu events)", count);
 
 rcu_error:
-       rcu_read_unlock();
 error:
        health_code_update();
        return ret;
@@ -4622,120 +4635,135 @@ int ust_app_list_event_fields(struct lttng_event_field **fields)
 
        nbmem = UST_APP_EVENT_LIST_SIZE;
        tmp_event = calloc<lttng_event_field>(nbmem);
-       if (tmp_event == NULL) {
+       if (tmp_event == nullptr) {
                PERROR("zmalloc ust app event fields");
                ret = -ENOMEM;
                goto error;
        }
 
-       rcu_read_lock();
+       {
+               lttng::urcu::read_lock_guard read_lock;
 
-       cds_lfht_for_each_entry (ust_app_ht->ht, &iter.iter, app, pid_n.node) {
-               struct lttng_ust_abi_field_iter uiter;
+               cds_lfht_for_each_entry (ust_app_ht->ht, &iter.iter, app, pid_n.node) {
+                       struct lttng_ust_abi_field_iter uiter;
 
-               health_code_update();
+                       health_code_update();
 
-               if (!app->compatible) {
-                       /*
-                        * TODO: In time, we should notice the caller of this error by
-                        * telling him that this is a version error.
-                        */
-                       continue;
-               }
-               pthread_mutex_lock(&app->sock_lock);
-               handle = lttng_ust_ctl_tracepoint_field_list(app->sock);
-               if (handle < 0) {
-                       if (handle != -EPIPE && handle != -LTTNG_UST_ERR_EXITING) {
-                               ERR("UST app list field getting handle failed for app pid %d",
-                                   app->pid);
+                       if (!app->compatible) {
+                               /*
+                                * TODO: In time, we should notice the caller of this error by
+                                * telling him that this is a version error.
+                                */
+                               continue;
                        }
-                       pthread_mutex_unlock(&app->sock_lock);
-                       continue;
-               }
 
-               while ((ret = lttng_ust_ctl_tracepoint_field_list_get(app->sock, handle, &uiter)) !=
-                      -LTTNG_UST_ERR_NOENT) {
-                       /* Handle ustctl error. */
-                       if (ret < 0) {
-                               int release_ret;
-
-                               if (ret != -LTTNG_UST_ERR_EXITING && ret != -EPIPE) {
-                                       ERR("UST app tp list field failed for app %d with ret %d",
-                                           app->sock,
-                                           ret);
-                               } else {
-                                       DBG3("UST app tp list field failed. Application is dead");
-                                       break;
+                       pthread_mutex_lock(&app->sock_lock);
+                       handle = lttng_ust_ctl_tracepoint_field_list(app->sock);
+                       if (handle < 0) {
+                               if (handle != -EPIPE && handle != -LTTNG_UST_ERR_EXITING) {
+                                       ERR("UST app list field getting handle failed for app pid %d",
+                                           app->pid);
                                }
-                               free(tmp_event);
-                               release_ret = lttng_ust_ctl_release_handle(app->sock, handle);
                                pthread_mutex_unlock(&app->sock_lock);
-                               if (release_ret < 0 && release_ret != -LTTNG_UST_ERR_EXITING &&
-                                   release_ret != -EPIPE) {
-                                       ERR("Error releasing app handle for app %d with ret %d",
-                                           app->sock,
-                                           release_ret);
-                               }
-                               goto rcu_error;
+                               continue;
                        }
 
-                       health_code_update();
-                       if (count >= nbmem) {
-                               /* In case the realloc fails, we free the memory */
-                               struct lttng_event_field *new_tmp_event;
-                               size_t new_nbmem;
-
-                               new_nbmem = nbmem << 1;
-                               DBG2("Reallocating event field list from %zu to %zu entries",
-                                    nbmem,
-                                    new_nbmem);
-                               new_tmp_event = (lttng_event_field *) realloc(
-                                       tmp_event, new_nbmem * sizeof(struct lttng_event_field));
-                               if (new_tmp_event == NULL) {
+                       while ((ret = lttng_ust_ctl_tracepoint_field_list_get(
+                                       app->sock, handle, &uiter)) != -LTTNG_UST_ERR_NOENT) {
+                               /* Handle ustctl error. */
+                               if (ret < 0) {
                                        int release_ret;
 
-                                       PERROR("realloc ust app event fields");
+                                       if (ret != -LTTNG_UST_ERR_EXITING && ret != -EPIPE) {
+                                               ERR("UST app tp list field failed for app %d with ret %d",
+                                                   app->sock,
+                                                   ret);
+                                       } else {
+                                               DBG3("UST app tp list field failed. Application is dead");
+                                               break;
+                                       }
+
                                        free(tmp_event);
-                                       ret = -ENOMEM;
                                        release_ret =
                                                lttng_ust_ctl_release_handle(app->sock, handle);
                                        pthread_mutex_unlock(&app->sock_lock);
-                                       if (release_ret && release_ret != -LTTNG_UST_ERR_EXITING &&
+                                       if (release_ret < 0 &&
+                                           release_ret != -LTTNG_UST_ERR_EXITING &&
                                            release_ret != -EPIPE) {
                                                ERR("Error releasing app handle for app %d with ret %d",
                                                    app->sock,
                                                    release_ret);
                                        }
+
                                        goto rcu_error;
                                }
-                               /* Zero the new memory */
-                               memset(new_tmp_event + nbmem,
-                                      0,
-                                      (new_nbmem - nbmem) * sizeof(struct lttng_event_field));
-                               nbmem = new_nbmem;
-                               tmp_event = new_tmp_event;
+
+                               health_code_update();
+                               if (count >= nbmem) {
+                                       /* In case the realloc fails, we free the memory */
+                                       struct lttng_event_field *new_tmp_event;
+                                       size_t new_nbmem;
+
+                                       new_nbmem = nbmem << 1;
+                                       DBG2("Reallocating event field list from %zu to %zu entries",
+                                            nbmem,
+                                            new_nbmem);
+                                       new_tmp_event = (lttng_event_field *) realloc(
+                                               tmp_event,
+                                               new_nbmem * sizeof(struct lttng_event_field));
+                                       if (new_tmp_event == nullptr) {
+                                               int release_ret;
+
+                                               PERROR("realloc ust app event fields");
+                                               free(tmp_event);
+                                               ret = -ENOMEM;
+                                               release_ret = lttng_ust_ctl_release_handle(
+                                                       app->sock, handle);
+                                               pthread_mutex_unlock(&app->sock_lock);
+                                               if (release_ret &&
+                                                   release_ret != -LTTNG_UST_ERR_EXITING &&
+                                                   release_ret != -EPIPE) {
+                                                       ERR("Error releasing app handle for app %d with ret %d",
+                                                           app->sock,
+                                                           release_ret);
+                                               }
+
+                                               goto rcu_error;
+                                       }
+
+                                       /* Zero the new memory */
+                                       memset(new_tmp_event + nbmem,
+                                              0,
+                                              (new_nbmem - nbmem) *
+                                                      sizeof(struct lttng_event_field));
+                                       nbmem = new_nbmem;
+                                       tmp_event = new_tmp_event;
+                               }
+
+                               memcpy(tmp_event[count].field_name,
+                                      uiter.field_name,
+                                      LTTNG_UST_ABI_SYM_NAME_LEN);
+                               /* Mapping between these enums matches 1 to 1. */
+                               tmp_event[count].type = (enum lttng_event_field_type) uiter.type;
+                               tmp_event[count].nowrite = uiter.nowrite;
+
+                               memcpy(tmp_event[count].event.name,
+                                      uiter.event_name,
+                                      LTTNG_UST_ABI_SYM_NAME_LEN);
+                               tmp_event[count].event.loglevel = uiter.loglevel;
+                               tmp_event[count].event.type = LTTNG_EVENT_TRACEPOINT;
+                               tmp_event[count].event.pid = app->pid;
+                               tmp_event[count].event.enabled = -1;
+                               count++;
                        }
 
-                       memcpy(tmp_event[count].field_name,
-                              uiter.field_name,
-                              LTTNG_UST_ABI_SYM_NAME_LEN);
-                       /* Mapping between these enums matches 1 to 1. */
-                       tmp_event[count].type = (enum lttng_event_field_type) uiter.type;
-                       tmp_event[count].nowrite = uiter.nowrite;
-
-                       memcpy(tmp_event[count].event.name,
-                              uiter.event_name,
-                              LTTNG_UST_ABI_SYM_NAME_LEN);
-                       tmp_event[count].event.loglevel = uiter.loglevel;
-                       tmp_event[count].event.type = LTTNG_EVENT_TRACEPOINT;
-                       tmp_event[count].event.pid = app->pid;
-                       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) {
-                       ERR("Error releasing app handle for app %d with ret %d", app->sock, ret);
+                       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) {
+                               ERR("Error releasing app handle for app %d with ret %d",
+                                   app->sock,
+                                   ret);
+                       }
                }
        }
 
@@ -4745,7 +4773,6 @@ int ust_app_list_event_fields(struct lttng_event_field **fields)
        DBG2("UST app list event fields done (%zu events)", count);
 
 rcu_error:
-       rcu_read_unlock();
 error:
        health_code_update();
        return ret;
@@ -4754,7 +4781,7 @@ error:
 /*
  * Free and clean all traceable apps of the global list.
  */
-void ust_app_clean_list(void)
+void ust_app_clean_list()
 {
        int ret;
        struct ust_app *app;
@@ -4762,10 +4789,10 @@ void ust_app_clean_list(void)
 
        DBG2("UST app cleaning registered apps hash table");
 
-       rcu_read_lock();
-
        /* Cleanup notify socket hash table */
        if (ust_app_ht_by_notify_sock) {
+               lttng::urcu::read_lock_guard read_lock;
+
                cds_lfht_for_each_entry (
                        ust_app_ht_by_notify_sock->ht, &iter.iter, app, notify_sock_n.node) {
                        /*
@@ -4773,29 +4800,21 @@ void ust_app_clean_list(void)
                         * 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);
                }
        }
 
-       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) {
+               lttng::urcu::read_lock_guard read_lock;
+
                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);
                        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);
@@ -4811,7 +4830,7 @@ void ust_app_clean_list(void)
 /*
  * Init UST app hash table.
  */
-int ust_app_ht_alloc(void)
+int ust_app_ht_alloc()
 {
        ust_app_ht = lttng_ht_new(0, LTTNG_HT_TYPE_ULONG);
        if (!ust_app_ht) {
@@ -4845,42 +4864,43 @@ int ust_app_disable_channel_glb(struct ltt_ust_session *usess, struct ltt_ust_ch
             uchan->name,
             usess->id);
 
-       rcu_read_lock();
+       {
+               lttng::urcu::read_lock_guard read_lock;
 
-       /* For every registered applications */
-       cds_lfht_for_each_entry (ust_app_ht->ht, &iter.iter, app, pid_n.node) {
-               struct lttng_ht_iter uiter;
-               if (!app->compatible) {
-                       /*
-                        * TODO: In time, we should notice the caller of this error by
-                        * telling him that this is a version error.
-                        */
-                       continue;
-               }
-               ua_sess = lookup_session_by_app(usess, app);
-               if (ua_sess == NULL) {
-                       continue;
-               }
+               /* For every registered applications */
+               cds_lfht_for_each_entry (ust_app_ht->ht, &iter.iter, app, pid_n.node) {
+                       struct lttng_ht_iter uiter;
+                       if (!app->compatible) {
+                               /*
+                                * TODO: In time, we should notice the caller of this error by
+                                * telling him that this is a version error.
+                                */
+                               continue;
+                       }
+                       ua_sess = lookup_session_by_app(usess, app);
+                       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);
-               /* If the session if found for the app, the channel must be there */
-               LTTNG_ASSERT(ua_chan_node);
+                       /* Get channel */
+                       lttng_ht_lookup(ua_sess->channels, (void *) uchan->name, &uiter);
+                       ua_chan_node = lttng_ht_iter_get_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 */
-               LTTNG_ASSERT(ua_chan->enabled == 1);
+                       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);
 
-               /* Disable channel onto application */
-               ret = disable_ust_app_channel(ua_sess, ua_chan, app);
-               if (ret < 0) {
-                       /* XXX: We might want to report this error at some point... */
-                       continue;
+                       /* Disable channel onto application */
+                       ret = disable_ust_app_channel(ua_sess, ua_chan, app);
+                       if (ret < 0) {
+                               /* XXX: We might want to report this error at some point... */
+                               continue;
+                       }
                }
        }
 
-       rcu_read_unlock();
        return ret;
 }
 
@@ -4899,31 +4919,32 @@ int ust_app_enable_channel_glb(struct ltt_ust_session *usess, struct ltt_ust_cha
             uchan->name,
             usess->id);
 
-       rcu_read_lock();
+       {
+               lttng::urcu::read_lock_guard read_lock;
 
-       /* For every registered applications */
-       cds_lfht_for_each_entry (ust_app_ht->ht, &iter.iter, app, pid_n.node) {
-               if (!app->compatible) {
-                       /*
-                        * TODO: In time, we should notice the caller of this error by
-                        * telling him that this is a version error.
-                        */
-                       continue;
-               }
-               ua_sess = lookup_session_by_app(usess, app);
-               if (ua_sess == NULL) {
-                       continue;
-               }
+               /* For every registered applications */
+               cds_lfht_for_each_entry (ust_app_ht->ht, &iter.iter, app, pid_n.node) {
+                       if (!app->compatible) {
+                               /*
+                                * TODO: In time, we should notice the caller of this error by
+                                * telling him that this is a version error.
+                                */
+                               continue;
+                       }
+                       ua_sess = lookup_session_by_app(usess, app);
+                       if (ua_sess == nullptr) {
+                               continue;
+                       }
 
-               /* Enable channel onto application */
-               ret = enable_ust_app_channel(ua_sess, uchan, app);
-               if (ret < 0) {
-                       /* XXX: We might want to report this error at some point... */
-                       continue;
+                       /* Enable channel onto application */
+                       ret = enable_ust_app_channel(ua_sess, uchan, app);
+                       if (ret < 0) {
+                               /* XXX: We might want to report this error at some point... */
+                               continue;
+                       }
                }
        }
 
-       rcu_read_unlock();
        return ret;
 }
 
@@ -4949,58 +4970,62 @@ int ust_app_disable_event_glb(struct ltt_ust_session *usess,
            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) {
-               if (!app->compatible) {
-                       /*
-                        * TODO: In time, we should notice the caller of this error by
-                        * telling him that this is a version error.
-                        */
-                       continue;
-               }
-               ua_sess = lookup_session_by_app(usess, app);
-               if (ua_sess == NULL) {
-                       /* Next app */
-                       continue;
-               }
+       {
+               lttng::urcu::read_lock_guard read_lock;
 
-               /* 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);
-               if (ua_chan_node == NULL) {
-                       DBG2("Channel %s not found in session id %" PRIu64 " for app pid %d."
-                            "Skipping",
-                            uchan->name,
-                            usess->id,
-                            app->pid);
-                       continue;
-               }
-               ua_chan = lttng::utils::container_of(ua_chan_node, &ust_app_channel::node);
+               /* For all registered applications */
+               cds_lfht_for_each_entry (ust_app_ht->ht, &iter.iter, app, pid_n.node) {
+                       if (!app->compatible) {
+                               /*
+                                * TODO: In time, we should notice the caller of this error by
+                                * telling him that this is a version error.
+                                */
+                               continue;
+                       }
+                       ua_sess = lookup_session_by_app(usess, app);
+                       if (ua_sess == nullptr) {
+                               /* Next app */
+                               continue;
+                       }
 
-               ua_event = find_ust_app_event(ua_chan->events,
-                                             uevent->attr.name,
-                                             uevent->filter,
-                                             uevent->attr.loglevel,
-                                             uevent->exclusion);
-               if (ua_event == NULL) {
-                       DBG2("Event %s not found in channel %s for app pid %d."
-                            "Skipping",
-                            uevent->attr.name,
-                            uchan->name,
-                            app->pid);
-                       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);
+                       if (ua_chan_node == nullptr) {
+                               DBG2("Channel %s not found in session id %" PRIu64
+                                    " for app pid %d."
+                                    "Skipping",
+                                    uchan->name,
+                                    usess->id,
+                                    app->pid);
+                               continue;
+                       }
+                       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,
+                               (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",
+                                    uevent->attr.name,
+                                    uchan->name,
+                                    app->pid);
+                               continue;
+                       }
 
-               ret = disable_ust_app_event(ua_event, app);
-               if (ret < 0) {
-                       /* XXX: Report error someday... */
-                       continue;
+                       ret = disable_ust_app_event(ua_event, app);
+                       if (ret < 0) {
+                               /* XXX: Report error someday... */
+                               continue;
+                       }
                }
        }
 
-       rcu_read_unlock();
        return ret;
 }
 
@@ -5012,7 +5037,7 @@ static int ust_app_channel_create(struct ltt_ust_session *usess,
                                  struct ust_app_channel **_ua_chan)
 {
        int ret = 0;
-       struct ust_app_channel *ua_chan = NULL;
+       struct ust_app_channel *ua_chan = nullptr;
 
        LTTNG_ASSERT(ua_sess);
        ASSERT_LOCKED(ua_sess->lock);
@@ -5021,7 +5046,7 @@ static int ust_app_channel_create(struct ltt_ust_session *usess,
                copy_channel_attr_to_ustctl(&ua_sess->metadata_attr, &uchan->attr);
                ret = 0;
        } else {
-               struct ltt_ust_context *uctx = NULL;
+               struct ltt_ust_context *uctx = nullptr;
 
                /*
                 * Create channel onto application and synchronize its
@@ -5101,70 +5126,72 @@ int ust_app_enable_event_glb(struct ltt_ust_session *usess,
         * tracer also.
         */
 
-       rcu_read_lock();
+       {
+               lttng::urcu::read_lock_guard read_lock;
 
-       /* For all registered applications */
-       cds_lfht_for_each_entry (ust_app_ht->ht, &iter.iter, app, pid_n.node) {
-               if (!app->compatible) {
-                       /*
-                        * TODO: In time, we should notice the caller of this error by
-                        * telling him that this is a version error.
-                        */
-                       continue;
-               }
-               ua_sess = lookup_session_by_app(usess, app);
-               if (!ua_sess) {
-                       /* The application has problem or is probably dead. */
-                       continue;
-               }
+               /* For all registered applications */
+               cds_lfht_for_each_entry (ust_app_ht->ht, &iter.iter, app, pid_n.node) {
+                       if (!app->compatible) {
+                               /*
+                                * TODO: In time, we should notice the caller of this error by
+                                * telling him that this is a version error.
+                                */
+                               continue;
+                       }
+                       ua_sess = lookup_session_by_app(usess, app);
+                       if (!ua_sess) {
+                               /* The application has problem or is probably dead. */
+                               continue;
+                       }
 
-               pthread_mutex_lock(&ua_sess->lock);
+                       pthread_mutex_lock(&ua_sess->lock);
 
-               if (ua_sess->deleted) {
-                       pthread_mutex_unlock(&ua_sess->lock);
-                       continue;
-               }
+                       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);
-               ua_chan_node = lttng_ht_iter_get_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) {
-                       pthread_mutex_unlock(&ua_sess->lock);
-                       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);
+                       /*
+                        * 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);
+                       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,
+                               (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);
+                               goto next_app;
+                       }
 
-               /* Get event node */
-               ua_event = find_ust_app_event(ua_chan->events,
-                                             uevent->attr.name,
-                                             uevent->filter,
-                                             uevent->attr.loglevel,
-                                             uevent->exclusion);
-               if (ua_event == NULL) {
-                       DBG3("UST app enable event %s not found for app PID %d."
-                            "Skipping app",
-                            uevent->attr.name,
-                            app->pid);
-                       goto next_app;
-               }
-
-               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;
+                       }
+               next_app:
                        pthread_mutex_unlock(&ua_sess->lock);
-                       goto error;
                }
-       next_app:
-               pthread_mutex_unlock(&ua_sess->lock);
        }
-
 error:
-       rcu_read_unlock();
        return ret;
 }
 
@@ -5188,53 +5215,56 @@ int ust_app_create_event_glb(struct ltt_ust_session *usess,
            uevent->attr.name,
            usess->id);
 
-       rcu_read_lock();
+       {
+               lttng::urcu::read_lock_guard read_lock;
 
-       /* For all registered applications */
-       cds_lfht_for_each_entry (ust_app_ht->ht, &iter.iter, app, pid_n.node) {
-               if (!app->compatible) {
-                       /*
-                        * TODO: In time, we should notice the caller of this error by
-                        * telling him that this is a version error.
-                        */
-                       continue;
-               }
-               ua_sess = lookup_session_by_app(usess, app);
-               if (!ua_sess) {
-                       /* The application has problem or is probably dead. */
-                       continue;
-               }
+               /* For all registered applications */
+               cds_lfht_for_each_entry (ust_app_ht->ht, &iter.iter, app, pid_n.node) {
+                       if (!app->compatible) {
+                               /*
+                                * TODO: In time, we should notice the caller of this error by
+                                * telling him that this is a version error.
+                                */
+                               continue;
+                       }
 
-               pthread_mutex_lock(&ua_sess->lock);
+                       ua_sess = lookup_session_by_app(usess, app);
+                       if (!ua_sess) {
+                               /* The application has problem or is probably dead. */
+                               continue;
+                       }
 
-               if (ua_sess->deleted) {
-                       pthread_mutex_unlock(&ua_sess->lock);
-                       continue;
-               }
+                       pthread_mutex_lock(&ua_sess->lock);
 
-               /* 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);
-               /* If the channel is not found, there is a code flow error */
-               LTTNG_ASSERT(ua_chan_node);
+                       if (ua_sess->deleted) {
+                               pthread_mutex_unlock(&ua_sess->lock);
+                               continue;
+                       }
 
-               ua_chan = lttng::utils::container_of(ua_chan_node, &ust_app_channel::node);
+                       /* 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);
+                       /* If the channel is not found, there is a code flow error */
+                       LTTNG_ASSERT(ua_chan_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;
+                       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;
+                               }
+
+                               DBG2("UST app event %s already exist on app PID %d",
+                                    uevent->attr.name,
+                                    app->pid);
+                               continue;
                        }
-                       DBG2("UST app event %s already exist on app PID %d",
-                            uevent->attr.name,
-                            app->pid);
-                       continue;
                }
        }
 
-       rcu_read_unlock();
        return ret;
 }
 
@@ -5251,14 +5281,14 @@ 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);
 
-       rcu_read_lock();
+       lttng::urcu::read_lock_guard read_lock;
 
        if (!app->compatible) {
                goto end;
        }
 
        ua_sess = lookup_session_by_app(usess, app);
-       if (ua_sess == NULL) {
+       if (ua_sess == nullptr) {
                /* The session is in teardown process. Ignore and continue. */
                goto end;
        }
@@ -5311,8 +5341,8 @@ skip_setup:
        }
 
        /* Indicate that the session has been started once */
-       ua_sess->started = 1;
-       ua_sess->enabled = 1;
+       ua_sess->started = true;
+       ua_sess->enabled = true;
 
        pthread_mutex_unlock(&ua_sess->lock);
 
@@ -5340,13 +5370,11 @@ skip_setup:
        }
 
 end:
-       rcu_read_unlock();
        health_code_update();
        return 0;
 
 error_unlock:
        pthread_mutex_unlock(&ua_sess->lock);
-       rcu_read_unlock();
        health_code_update();
        return -1;
 }
@@ -5361,14 +5389,14 @@ 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);
 
-       rcu_read_lock();
+       lttng::urcu::read_lock_guard read_lock;
 
        if (!app->compatible) {
                goto end_no_session;
        }
 
        ua_sess = lookup_session_by_app(usess, app);
-       if (ua_sess == NULL) {
+       if (ua_sess == nullptr) {
                goto end_no_session;
        }
 
@@ -5417,7 +5445,7 @@ static int ust_app_stop_trace(struct ltt_ust_session *usess, struct ust_app *app
        }
 
        health_code_update();
-       ua_sess->enabled = 0;
+       ua_sess->enabled = false;
 
        /* Quiescent wait after stopping trace */
        pthread_mutex_lock(&app->sock_lock);
@@ -5455,47 +5483,46 @@ static int ust_app_stop_trace(struct ltt_ust_session *usess, struct ust_app *app
 end_unlock:
        pthread_mutex_unlock(&ua_sess->lock);
 end_no_session:
-       rcu_read_unlock();
        health_code_update();
        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;
        struct lttng_ht_iter iter;
        struct ust_app_channel *ua_chan;
        struct consumer_socket *socket;
 
-       DBG("Flushing app session buffers for ust app pid %d", app->pid);
+       DBG("Flushing app session buffers for ust app pid %d", app.pid);
 
-       rcu_read_lock();
-
-       if (!app->compatible) {
+       if (!app.compatible) {
                goto end_not_compatible;
        }
 
-       pthread_mutex_lock(&ua_sess->lock);
+       pthread_mutex_lock(&ua_sess.lock);
 
-       if (ua_sess->deleted) {
+       if (ua_sess.deleted) {
                goto end_deleted;
        }
 
        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. */
-       switch (ua_sess->buffer_type) {
+       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) {
+       {
+               lttng::urcu::read_lock_guard read_lock;
+
+               cds_lfht_for_each_entry (ua_sess.channels->ht, &iter.iter, ua_chan, node.node) {
                        health_code_update();
                        ret = consumer_flush_channel(socket, ua_chan->key);
                        if (ret) {
@@ -5504,7 +5531,9 @@ static int ust_app_flush_app_session(struct ust_app *app, struct ust_app_session
                                continue;
                        }
                }
+
                break;
+       }
        case LTTNG_BUFFER_PER_UID:
        default:
                abort();
@@ -5514,10 +5543,9 @@ static int ust_app_flush_app_session(struct ust_app *app, struct ust_app_session
        health_code_update();
 
 end_deleted:
-       pthread_mutex_unlock(&ua_sess->lock);
+       pthread_mutex_unlock(&ua_sess.lock);
 
 end_not_compatible:
-       rcu_read_unlock();
        health_code_update();
        return retval;
 }
@@ -5533,8 +5561,6 @@ static int ust_app_flush_session(struct ltt_ust_session *usess)
 
        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:
@@ -5544,6 +5570,7 @@ static int ust_app_flush_session(struct ltt_ust_session *usess)
 
                /* Flush all per UID buffers associated to that session. */
                cds_list_for_each_entry (reg, &usess->buffer_reg_uid_list, lnode) {
+                       lttng::urcu::read_lock_guard read_lock;
                        lsu::registry_session *ust_session_reg;
                        struct buffer_reg_channel *buf_reg_chan;
                        struct consumer_socket *socket;
@@ -5571,6 +5598,7 @@ 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);
                }
+
                break;
        }
        case LTTNG_BUFFER_PER_PID:
@@ -5578,14 +5606,17 @@ static int ust_app_flush_session(struct ltt_ust_session *usess)
                struct ust_app_session *ua_sess;
                struct lttng_ht_iter iter;
                struct ust_app *app;
+               lttng::urcu::read_lock_guard read_lock;
 
                cds_lfht_for_each_entry (ust_app_ht->ht, &iter.iter, app, pid_n.node) {
                        ua_sess = lookup_session_by_app(usess, app);
-                       if (ua_sess == NULL) {
+                       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:
@@ -5594,7 +5625,6 @@ static int ust_app_flush_session(struct ltt_ust_session *usess)
                break;
        }
 
-       rcu_read_unlock();
        health_code_update();
        return ret;
 }
@@ -5608,7 +5638,7 @@ static int ust_app_clear_quiescent_app_session(struct ust_app *app, struct ust_a
 
        DBG("Clearing stream quiescent state for ust app pid %d", app->pid);
 
-       rcu_read_lock();
+       lttng::urcu::read_lock_guard read_lock;
 
        if (!app->compatible) {
                goto end_not_compatible;
@@ -5655,7 +5685,6 @@ end_unlock:
        pthread_mutex_unlock(&ua_sess->lock);
 
 end_not_compatible:
-       rcu_read_unlock();
        health_code_update();
        return ret;
 }
@@ -5672,8 +5701,6 @@ static int ust_app_clear_quiescent_session(struct ltt_ust_session *usess)
 
        DBG("Clearing stream quiescent state for all ust apps");
 
-       rcu_read_lock();
-
        switch (usess->buffer_type) {
        case LTTNG_BUFFER_PER_UID:
        {
@@ -5687,6 +5714,7 @@ static int ust_app_clear_quiescent_session(struct ltt_ust_session *usess)
                cds_list_for_each_entry (reg, &usess->buffer_reg_uid_list, lnode) {
                        struct consumer_socket *socket;
                        struct buffer_reg_channel *buf_reg_chan;
+                       lttng::urcu::read_lock_guard read_lock;
 
                        /* Get associated consumer socket.*/
                        socket = consumer_find_socket_by_bitness(reg->bits_per_long,
@@ -5711,6 +5739,7 @@ static int ust_app_clear_quiescent_session(struct ltt_ust_session *usess)
                                                                        buf_reg_chan->consumer_key);
                        }
                }
+
                break;
        }
        case LTTNG_BUFFER_PER_PID:
@@ -5718,14 +5747,16 @@ static int ust_app_clear_quiescent_session(struct ltt_ust_session *usess)
                struct ust_app_session *ua_sess;
                struct lttng_ht_iter iter;
                struct ust_app *app;
+               lttng::urcu::read_lock_guard read_lock;
 
                cds_lfht_for_each_entry (ust_app_ht->ht, &iter.iter, app, pid_n.node) {
                        ua_sess = lookup_session_by_app(usess, app);
-                       if (ua_sess == NULL) {
+                       if (ua_sess == nullptr) {
                                continue;
                        }
                        (void) ust_app_clear_quiescent_app_session(app, ua_sess);
                }
+
                break;
        }
        default:
@@ -5734,7 +5765,6 @@ static int ust_app_clear_quiescent_session(struct ltt_ust_session *usess)
                break;
        }
 
-       rcu_read_unlock();
        health_code_update();
        return ret;
 }
@@ -5751,7 +5781,7 @@ static int destroy_trace(struct ltt_ust_session *usess, struct ust_app *app)
 
        DBG("Destroy tracing for ust app pid %d", app->pid);
 
-       rcu_read_lock();
+       lttng::urcu::read_lock_guard read_lock;
 
        if (!app->compatible) {
                goto end;
@@ -5759,7 +5789,7 @@ static int destroy_trace(struct ltt_ust_session *usess, struct ust_app *app)
 
        __lookup_session_by_app(usess, app, &iter);
        node = lttng_ht_iter_get_node_u64(&iter);
-       if (node == NULL) {
+       if (node == nullptr) {
                /* Session is being or is deleted. */
                goto end;
        }
@@ -5791,7 +5821,6 @@ static int destroy_trace(struct ltt_ust_session *usess, struct ust_app *app)
                }
        }
 end:
-       rcu_read_unlock();
        health_code_update();
        return 0;
 }
@@ -5810,9 +5839,7 @@ int ust_app_start_trace_all(struct ltt_ust_session *usess)
         * 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
@@ -5822,11 +5849,13 @@ int ust_app_start_trace_all(struct ltt_ust_session *usess)
         */
        (void) ust_app_clear_quiescent_session(usess);
 
-       cds_lfht_for_each_entry (ust_app_ht->ht, &iter.iter, app, pid_n.node) {
-               ust_app_global_update(usess, app);
-       }
+       {
+               lttng::urcu::read_lock_guard read_lock;
 
-       rcu_read_unlock();
+               cds_lfht_for_each_entry (ust_app_ht->ht, &iter.iter, app, pid_n.node) {
+                       ust_app_global_update(usess, app);
+               }
+       }
 
        return 0;
 }
@@ -5847,22 +5876,22 @@ 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.
         */
-       usess->active = 0;
+       usess->active = false;
 
-       rcu_read_lock();
+       {
+               lttng::urcu::read_lock_guard read_lock;
 
-       cds_lfht_for_each_entry (ust_app_ht->ht, &iter.iter, app, pid_n.node) {
-               ret = ust_app_stop_trace(usess, app);
-               if (ret < 0) {
-                       /* Continue to next apps even on error */
-                       continue;
+               cds_lfht_for_each_entry (ust_app_ht->ht, &iter.iter, app, pid_n.node) {
+                       ret = ust_app_stop_trace(usess, app);
+                       if (ret < 0) {
+                               /* Continue to next apps even on error */
+                               continue;
+                       }
                }
        }
 
        (void) ust_app_flush_session(usess);
 
-       rcu_read_unlock();
-
        return 0;
 }
 
@@ -5877,18 +5906,18 @@ int ust_app_destroy_trace_all(struct ltt_ust_session *usess)
 
        DBG("Destroy all UST traces");
 
-       rcu_read_lock();
+       {
+               lttng::urcu::read_lock_guard 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;
+               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;
+                       }
                }
        }
 
-       rcu_read_unlock();
-
        return 0;
 }
 
@@ -5923,11 +5952,12 @@ static int ust_app_channel_synchronize_event(struct ust_app_channel *ua_chan,
                                             struct ust_app *app)
 {
        int ret = 0;
-       struct ust_app_event *ua_event = NULL;
+       struct ust_app_event *ua_event = nullptr;
 
        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) {
@@ -5953,7 +5983,7 @@ static void ust_app_synchronize_event_notifier_rules(struct ust_app *app)
        enum lttng_error_code ret_code;
        enum lttng_trigger_status t_status;
        struct lttng_ht_iter app_trigger_iter;
-       struct lttng_triggers *triggers = NULL;
+       struct lttng_triggers *triggers = nullptr;
        struct ust_app_event_notifier_rule *event_notifier_rule;
        unsigned int count, i;
 
@@ -6038,54 +6068,55 @@ static void ust_app_synchronize_event_notifier_rules(struct ust_app *app)
                }
        }
 
-       rcu_read_lock();
-       /* 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) {
-               const uint64_t app_token = event_notifier_rule->token;
-               bool found = false;
+       {
+               lttng::urcu::read_lock_guard read_lock;
 
-               /*
-                * Check if the app event trigger still exists on the
-                * notification side.
-                */
-               for (i = 0; i < count; i++) {
-                       uint64_t notification_thread_token;
-                       const struct lttng_trigger *trigger =
-                               lttng_triggers_get_at_index(triggers, i);
+               /* 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) {
+                       const uint64_t app_token = event_notifier_rule->token;
+                       bool found = false;
+
+                       /*
+                        * Check if the app event trigger still exists on the
+                        * notification side.
+                        */
+                       for (i = 0; i < count; i++) {
+                               uint64_t notification_thread_token;
+                               const struct lttng_trigger *trigger =
+                                       lttng_triggers_get_at_index(triggers, i);
 
-                       LTTNG_ASSERT(trigger);
+                               LTTNG_ASSERT(trigger);
 
-                       notification_thread_token = lttng_trigger_get_tracer_token(trigger);
+                               notification_thread_token = lttng_trigger_get_tracer_token(trigger);
 
-                       if (notification_thread_token == app_token) {
-                               found = true;
-                               break;
+                               if (notification_thread_token == app_token) {
+                                       found = true;
+                                       break;
+                               }
                        }
-               }
 
-               if (found) {
-                       /* Still valid. */
-                       continue;
-               }
+                       if (found) {
+                               /* Still valid. */
+                               continue;
+                       }
 
-               /*
-                * 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);
-               LTTNG_ASSERT(ret == 0);
+                       /*
+                        * 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);
+                       LTTNG_ASSERT(ret == 0);
 
-               /* Callee logs errors. */
-               (void) disable_ust_object(app, event_notifier_rule->obj);
+                       /* 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;
@@ -6156,7 +6187,7 @@ end:
 static void ust_app_synchronize(struct ltt_ust_session *usess, struct ust_app *app)
 {
        int ret = 0;
-       struct ust_app_session *ua_sess = NULL;
+       struct ust_app_session *ua_sess = nullptr;
 
        /*
         * The application's configuration should only be synchronized for
@@ -6164,14 +6195,12 @@ static void ust_app_synchronize(struct ltt_ust_session *usess, struct ust_app *a
         */
        LTTNG_ASSERT(usess->active);
 
-       ret = find_or_create_ust_app_session(usess, app, &ua_sess, NULL);
+       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;
        }
+
        LTTNG_ASSERT(ua_sess);
 
        pthread_mutex_lock(&ua_sess->lock);
@@ -6179,28 +6208,28 @@ static void ust_app_synchronize(struct ltt_ust_session *usess, struct ust_app *a
                goto deleted_session;
        }
 
-       rcu_read_lock();
+       {
+               lttng::urcu::read_lock_guard read_lock;
 
-       ust_app_synchronize_all_channels(usess, ua_sess, app);
+               ust_app_synchronize_all_channels(usess, 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(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:
@@ -6212,7 +6241,7 @@ static void ust_app_global_destroy(struct ltt_ust_session *usess, struct ust_app
        struct ust_app_session *ua_sess;
 
        ua_sess = lookup_session_by_app(usess, app);
-       if (ua_sess == NULL) {
+       if (ua_sess == nullptr) {
                return;
        }
        destroy_app_session(app, ua_sess);
@@ -6267,7 +6296,7 @@ void ust_app_global_update_event_notifier_rules(struct ust_app *app)
                return;
        }
 
-       if (app->event_notifier_group.object == NULL) {
+       if (app->event_notifier_group.object == nullptr) {
                WARN("UST app global update of event notifiers for app skipped since communication handle is null: app = '%s', pid = %d",
                     app->name,
                     app->pid);
@@ -6285,24 +6314,24 @@ 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) {
-               ust_app_global_update(usess, app);
+       {
+               lttng::urcu::read_lock_guard read_lock;
+
+               cds_lfht_for_each_entry (ust_app_ht->ht, &iter.iter, app, pid_n.node) {
+                       ust_app_global_update(usess, app);
+               }
        }
-       rcu_read_unlock();
 }
 
-void ust_app_global_update_all_event_notifier_rules(void)
+void ust_app_global_update_all_event_notifier_rules()
 {
        struct lttng_ht_iter iter;
        struct ust_app *app;
 
-       rcu_read_lock();
+       lttng::urcu::read_lock_guard read_lock;
        cds_lfht_for_each_entry (ust_app_ht->ht, &iter.iter, app, pid_n.node) {
                ust_app_global_update_event_notifier_rules(app);
        }
-
-       rcu_read_unlock();
 }
 
 /*
@@ -6315,49 +6344,50 @@ int ust_app_add_ctx_channel_glb(struct ltt_ust_session *usess,
        int ret = 0;
        struct lttng_ht_node_str *ua_chan_node;
        struct lttng_ht_iter iter, uiter;
-       struct ust_app_channel *ua_chan = NULL;
+       struct ust_app_channel *ua_chan = nullptr;
        struct ust_app_session *ua_sess;
        struct ust_app *app;
 
        LTTNG_ASSERT(usess->active);
 
-       rcu_read_lock();
-       cds_lfht_for_each_entry (ust_app_ht->ht, &iter.iter, app, pid_n.node) {
-               if (!app->compatible) {
-                       /*
-                        * TODO: In time, we should notice the caller of this error by
-                        * telling him that this is a version error.
-                        */
-                       continue;
-               }
-               ua_sess = lookup_session_by_app(usess, app);
-               if (ua_sess == NULL) {
-                       continue;
-               }
+       {
+               lttng::urcu::read_lock_guard read_lock;
+               cds_lfht_for_each_entry (ust_app_ht->ht, &iter.iter, app, pid_n.node) {
+                       if (!app->compatible) {
+                               /*
+                                * TODO: In time, we should notice the caller of this error by
+                                * telling him that this is a version error.
+                                */
+                               continue;
+                       }
+                       ua_sess = lookup_session_by_app(usess, app);
+                       if (ua_sess == nullptr) {
+                               continue;
+                       }
 
-               pthread_mutex_lock(&ua_sess->lock);
+                       pthread_mutex_lock(&ua_sess->lock);
 
-               if (ua_sess->deleted) {
-                       pthread_mutex_unlock(&ua_sess->lock);
-                       continue;
-               }
+                       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);
-               ua_chan_node = lttng_ht_iter_get_node_str(&uiter);
-               if (ua_chan_node == NULL) {
-                       goto next_app;
-               }
-               ua_chan = caa_container_of(ua_chan_node, struct ust_app_channel, node);
-               ret = create_ust_app_channel_context(ua_chan, &uctx->ctx, app);
-               if (ret < 0) {
-                       goto next_app;
+                       /* 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);
+                       if (ua_chan_node == nullptr) {
+                               goto next_app;
+                       }
+                       ua_chan = caa_container_of(ua_chan_node, struct ust_app_channel, node);
+                       ret = create_ust_app_channel_context(ua_chan, &uctx->ctx, app);
+                       if (ret < 0) {
+                               goto next_app;
+                       }
+               next_app:
+                       pthread_mutex_unlock(&ua_sess->lock);
                }
-       next_app:
-               pthread_mutex_unlock(&ua_sess->lock);
        }
 
-       rcu_read_unlock();
        return ret;
 }
 
@@ -6427,14 +6457,14 @@ static struct ust_app_session *find_session_by_objd(struct ust_app *app, int obj
 {
        struct lttng_ht_node_ulong *node;
        struct lttng_ht_iter iter;
-       struct ust_app_session *ua_sess = NULL;
+       struct ust_app_session *ua_sess = nullptr;
 
        LTTNG_ASSERT(app);
        ASSERT_RCU_READ_LOCKED();
 
        lttng_ht_lookup(app->ust_sessions_objd, (void *) ((unsigned long) objd), &iter);
        node = lttng_ht_iter_get_node_ulong(&iter);
-       if (node == NULL) {
+       if (node == nullptr) {
                DBG2("UST app session find by objd %d not found", objd);
                goto error;
        }
@@ -6454,14 +6484,14 @@ static struct ust_app_channel *find_channel_by_objd(struct ust_app *app, int obj
 {
        struct lttng_ht_node_ulong *node;
        struct lttng_ht_iter iter;
-       struct ust_app_channel *ua_chan = NULL;
+       struct ust_app_channel *ua_chan = nullptr;
 
        LTTNG_ASSERT(app);
        ASSERT_RCU_READ_LOCKED();
 
        lttng_ht_lookup(app->ust_objd, (void *) ((unsigned long) objd), &iter);
        node = lttng_ht_iter_get_node_ulong(&iter);
-       if (node == NULL) {
+       if (node == nullptr) {
                DBG2("UST app channel find by objd %d not found", objd);
                goto error;
        }
@@ -6492,7 +6522,8 @@ 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 =
-               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;
 
@@ -6586,7 +6617,7 @@ static int handle_app_register_channel_notification(int sock,
                                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;
@@ -6656,9 +6687,11 @@ static int add_event_ust_registry(int sock,
        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);
+       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);
@@ -6779,8 +6812,9 @@ static int add_enum_ust_registry(int sock,
        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);
+       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);
@@ -6816,7 +6850,7 @@ static int add_enum_ust_registry(int sock,
                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)
@@ -7049,7 +7083,7 @@ void ust_app_notify_sock_unregister(int sock)
 
        LTTNG_ASSERT(sock >= 0);
 
-       rcu_read_lock();
+       lttng::urcu::read_lock_guard read_lock;
 
        obj = zmalloc<ust_app_notify_sock_obj>();
        if (!obj) {
@@ -7096,7 +7130,6 @@ void ust_app_notify_sock_unregister(int sock)
        (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
@@ -7111,13 +7144,9 @@ close_socket:
 /*
  * 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);
 }
 
 /*
@@ -7134,18 +7163,18 @@ enum lttng_error_code ust_app_snapshot_record(const struct ltt_ust_session *uses
        enum lttng_error_code status = LTTNG_OK;
        struct lttng_ht_iter iter;
        struct ust_app *app;
-       char *trace_path = NULL;
+       char *trace_path = nullptr;
 
        LTTNG_ASSERT(usess);
        LTTNG_ASSERT(output);
 
-       rcu_read_lock();
-
        switch (usess->buffer_type) {
        case LTTNG_BUFFER_PER_UID:
        {
                struct buffer_reg_uid *reg;
 
+               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;
                        struct consumer_socket *socket;
@@ -7208,10 +7237,13 @@ enum lttng_error_code ust_app_snapshot_record(const struct ltt_ust_session *uses
                                goto error;
                        }
                }
+
                break;
        }
        case LTTNG_BUFFER_PER_PID:
        {
+               lttng::urcu::read_lock_guard read_lock;
+
                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;
@@ -7298,7 +7330,6 @@ enum lttng_error_code ust_app_snapshot_record(const struct ltt_ust_session *uses
 
 error:
        free(trace_path);
-       rcu_read_unlock();
        return status;
 }
 
@@ -7322,7 +7353,8 @@ uint64_t ust_app_get_size_one_more_packet_per_stream(const struct ltt_ust_sessio
                cds_list_for_each_entry (reg, &usess->buffer_reg_uid_list, lnode) {
                        struct buffer_reg_channel *buf_reg_chan;
 
-                       rcu_read_lock();
+                       lttng::urcu::read_lock_guard read_lock;
+
                        cds_lfht_for_each_entry (
                                reg->registry->channels->ht, &iter.iter, buf_reg_chan, node.node) {
                                if (cur_nr_packets >= buf_reg_chan->num_subbuf) {
@@ -7334,13 +7366,13 @@ 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;
                        }
-                       rcu_read_unlock();
                }
                break;
        }
        case LTTNG_BUFFER_PER_PID:
        {
-               rcu_read_lock();
+               lttng::urcu::read_lock_guard 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;
@@ -7364,7 +7396,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;
                        }
                }
-               rcu_read_unlock();
                break;
        }
        default:
@@ -7425,16 +7456,17 @@ int ust_app_pid_get_channel_runtime_stats(struct ltt_ust_session *usess,
        *discarded = 0;
        *lost = 0;
 
-       rcu_read_lock();
        /*
         * Iterate over every registered applications. Sum counters for
         * all applications containing requested session and channel.
         */
+       lttng::urcu::read_lock_guard read_lock;
+
        cds_lfht_for_each_entry (ust_app_ht->ht, &iter.iter, app, pid_n.node) {
                struct lttng_ht_iter uiter;
 
                ua_sess = lookup_session_by_app(usess, app);
-               if (ua_sess == NULL) {
+               if (ua_sess == nullptr) {
                        continue;
                }
 
@@ -7466,7 +7498,6 @@ int ust_app_pid_get_channel_runtime_stats(struct ltt_ust_session *usess,
                }
        }
 
-       rcu_read_unlock();
        return ret;
 }
 
@@ -7477,10 +7508,10 @@ static int ust_app_regenerate_statedump(struct ltt_ust_session *usess, struct us
 
        DBG("Regenerating the metadata for ust app pid %d", app->pid);
 
-       rcu_read_lock();
+       lttng::urcu::read_lock_guard read_lock;
 
        ua_sess = lookup_session_by_app(usess, app);
-       if (ua_sess == NULL) {
+       if (ua_sess == nullptr) {
                /* The session is in teardown process. Ignore and continue. */
                goto end;
        }
@@ -7499,7 +7530,6 @@ end_unlock:
        pthread_mutex_unlock(&ua_sess->lock);
 
 end:
-       rcu_read_unlock();
        health_code_update();
        return ret;
 }
@@ -7515,7 +7545,7 @@ int ust_app_regenerate_statedump_all(struct ltt_ust_session *usess)
 
        DBG("Regenerating the metadata for all UST apps");
 
-       rcu_read_lock();
+       lttng::urcu::read_lock_guard read_lock;
 
        cds_lfht_for_each_entry (ust_app_ht->ht, &iter.iter, app, pid_n.node) {
                if (!app->compatible) {
@@ -7529,8 +7559,6 @@ int ust_app_regenerate_statedump_all(struct ltt_ust_session *usess)
                }
        }
 
-       rcu_read_unlock();
-
        return 0;
 }
 
@@ -7544,13 +7572,10 @@ enum lttng_error_code ust_app_rotate_session(struct ltt_session *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();
-
        switch (usess->buffer_type) {
        case LTTNG_BUFFER_PER_UID:
        {
@@ -7559,6 +7584,7 @@ enum lttng_error_code ust_app_rotate_session(struct ltt_session *session)
                cds_list_for_each_entry (reg, &usess->buffer_reg_uid_list, lnode) {
                        struct buffer_reg_channel *buf_reg_chan;
                        struct consumer_socket *socket;
+                       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,
@@ -7612,14 +7638,28 @@ enum lttng_error_code ust_app_rotate_session(struct ltt_session *session)
        }
        case LTTNG_BUFFER_PER_PID:
        {
-               cds_lfht_for_each_entry (ust_app_ht->ht, &iter.iter, app, pid_n.node) {
+               lttng::urcu::read_lock_guard read_lock;
+               ust_app *raw_app;
+
+               cds_lfht_for_each_entry (ust_app_ht->ht, &iter.iter, raw_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;
+                       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 = lookup_session_by_app(usess, app.get());
                        if (!ua_sess) {
                                /* Session not associated with this app. */
                                continue;
@@ -7634,10 +7674,7 @@ enum lttng_error_code ust_app_rotate_session(struct ltt_session *session)
                        }
 
                        registry = get_session_registry(ua_sess);
-                       if (!registry) {
-                               DBG("Application session is being torn down. Skip application.");
-                               continue;
-                       }
+                       LTTNG_ASSERT(registry);
 
                        /* Rotate the data channels. */
                        cds_lfht_for_each_entry (
@@ -7647,9 +7684,6 @@ enum lttng_error_code ust_app_rotate_session(struct ltt_session *session)
                                                              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;
                                }
@@ -7661,18 +7695,17 @@ enum lttng_error_code ust_app_rotate_session(struct ltt_session *session)
 
                                (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) {
-                               /* Per-PID buffer and application going away. */
-                               if (ret == -LTTNG_ERR_CHAN_NOT_FOUND)
-                                       continue;
                                cmd_ret = LTTNG_ERR_ROTATION_FAIL_CONSUMER;
                                goto error;
                        }
                }
+
                break;
        }
        default:
@@ -7683,7 +7716,6 @@ enum lttng_error_code ust_app_rotate_session(struct ltt_session *session)
        cmd_ret = LTTNG_OK;
 
 error:
-       rcu_read_unlock();
        return cmd_ret;
 }
 
@@ -7696,12 +7728,12 @@ enum lttng_error_code ust_app_create_channel_subdirectories(const struct ltt_ust
        int fmt_ret;
 
        LTTNG_ASSERT(usess->current_trace_chunk);
-       rcu_read_lock();
 
        switch (usess->buffer_type) {
        case LTTNG_BUFFER_PER_UID:
        {
                struct buffer_reg_uid *reg;
+               lttng::urcu::read_lock_guard read_lock;
 
                cds_list_for_each_entry (reg, &usess->buffer_reg_uid_list, lnode) {
                        fmt_ret = asprintf(&pathname_index,
@@ -7732,6 +7764,7 @@ enum lttng_error_code ust_app_create_channel_subdirectories(const struct ltt_ust
        case LTTNG_BUFFER_PER_PID:
        {
                struct ust_app *app;
+               lttng::urcu::read_lock_guard read_lock;
 
                /*
                 * Create the toplevel ust/ directory in case no apps are running.
@@ -7787,7 +7820,6 @@ enum lttng_error_code ust_app_create_channel_subdirectories(const struct ltt_ust
 
        ret = LTTNG_OK;
 error:
-       rcu_read_unlock();
        return ret;
 }
 
@@ -7806,8 +7838,6 @@ enum lttng_error_code ust_app_clear_session(struct ltt_session *session)
 
        LTTNG_ASSERT(usess);
 
-       rcu_read_lock();
-
        if (usess->active) {
                ERR("Expecting inactive session %s (%" PRIu64 ")", session->name, session->id);
                cmd_ret = LTTNG_ERR_FATAL;
@@ -7818,6 +7848,7 @@ enum lttng_error_code ust_app_clear_session(struct ltt_session *session)
        case LTTNG_BUFFER_PER_UID:
        {
                struct buffer_reg_uid *reg;
+               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;
@@ -7859,6 +7890,8 @@ enum lttng_error_code ust_app_clear_session(struct ltt_session *session)
        }
        case LTTNG_BUFFER_PER_PID:
        {
+               lttng::urcu::read_lock_guard read_lock;
+
                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;
@@ -7939,7 +7972,6 @@ error:
 
 error_socket:
 end:
-       rcu_read_unlock();
        return cmd_ret;
 }
 
@@ -7967,8 +7999,6 @@ enum lttng_error_code ust_app_open_packets(struct ltt_session *session)
 
        LTTNG_ASSERT(usess);
 
-       rcu_read_lock();
-
        switch (usess->buffer_type) {
        case LTTNG_BUFFER_PER_UID:
        {
@@ -7977,6 +8007,7 @@ enum lttng_error_code ust_app_open_packets(struct ltt_session *session)
                cds_list_for_each_entry (reg, &usess->buffer_reg_uid_list, lnode) {
                        struct buffer_reg_channel *buf_reg_chan;
                        struct consumer_socket *socket;
+                       lttng::urcu::read_lock_guard read_lock;
 
                        socket = consumer_find_socket_by_bitness(reg->bits_per_long,
                                                                 usess->consumer);
@@ -8001,6 +8032,7 @@ enum lttng_error_code ust_app_open_packets(struct ltt_session *session)
        case LTTNG_BUFFER_PER_PID:
        {
                struct ust_app *app;
+               lttng::urcu::read_lock_guard read_lock;
 
                cds_lfht_for_each_entry (ust_app_ht->ht, &iter.iter, app, pid_n.node) {
                        struct consumer_socket *socket;
@@ -8056,7 +8088,6 @@ enum lttng_error_code ust_app_open_packets(struct ltt_session *session)
        }
 
 error:
-       rcu_read_unlock();
        return ret;
 }
 
@@ -8085,4 +8116,26 @@ 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;
-}
\ 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);
+}
This page took 0.102529 seconds and 4 git commands to generate.