X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Fust-app.cpp;h=88db75f8f4d7da8f1f2ae5cc3d7978cae26fafdd;hb=HEAD;hp=122bbddaf02fe99289c44207ff2bff657faec784;hpb=28ab034a2c3582d07d3423d2d746731f87d3969f;p=lttng-tools.git diff --git a/src/bin/lttng-sessiond/ust-app.cpp b/src/bin/lttng-sessiond/ust-app.cpp index 122bbddaf..d993b7b44 100644 --- a/src/bin/lttng-sessiond/ust-app.cpp +++ b/src/bin/lttng-sessiond/ust-app.cpp @@ -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 #include #include +#include #include #include @@ -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(); - 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(); - 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(); - 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(); - 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(); - 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(); - 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(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(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(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(); - if (lta == NULL) { + if (lta == nullptr) { PERROR("malloc"); goto error_free_pipe; } + urcu_ref_init(<a->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(<a->pid_n, (unsigned long) lta->pid); lta->sock = sock; - pthread_mutex_init(<a->sock_lock, NULL); + pthread_mutex_init(<a->sock_lock, nullptr); lttng_ht_node_init_ulong(<a->sock_n, (unsigned long) lta->sock); CDS_INIT_LIST_HEAD(<a->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, <a->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 = <a->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 = <a->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(<a->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(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(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; @@ -5995,8 +6025,8 @@ static void ust_app_synchronize_event_notifier_rules(struct ust_app *app) } for (i = 0; i < count; i++) { - struct lttng_condition *condition; - struct lttng_event_rule *event_rule; + const struct lttng_condition *condition; + const struct lttng_event_rule *event_rule; struct lttng_trigger *trigger; const struct ust_app_event_notifier_rule *looked_up_event_notifier_rule; enum lttng_condition_status condition_status; @@ -6006,7 +6036,7 @@ static void ust_app_synchronize_event_notifier_rules(struct ust_app *app) LTTNG_ASSERT(trigger); token = lttng_trigger_get_tracer_token(trigger); - condition = lttng_trigger_get_condition(trigger); + condition = lttng_trigger_get_const_condition(trigger); if (lttng_condition_get_type(condition) != LTTNG_CONDITION_TYPE_EVENT_RULE_MATCHES) { @@ -6014,8 +6044,8 @@ static void ust_app_synchronize_event_notifier_rules(struct ust_app *app) continue; } - condition_status = lttng_condition_event_rule_matches_borrow_rule_mutable( - condition, &event_rule); + condition_status = + lttng_condition_event_rule_matches_get_rule(condition, &event_rule); LTTNG_ASSERT(condition_status == LTTNG_CONDITION_STATUS_OK); if (lttng_event_rule_get_domain_type(event_rule) == LTTNG_DOMAIN_KERNEL) { @@ -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(raw_context_fields); + lttng::make_unique_wrapper( + 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(raw_signature); - auto fields = lttng::make_unique_wrapper(raw_fields); - auto model_emf_uri = lttng::make_unique_wrapper(raw_model_emf_uri); + auto signature = lttng::make_unique_wrapper(raw_signature); + auto fields = + lttng::make_unique_wrapper(raw_fields); + auto model_emf_uri = + lttng::make_unique_wrapper(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( - raw_entries); + auto entries = + lttng::make_unique_wrapper( + 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(); 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); +}