-static
-void destroy_channel_rcu(struct rcu_head *head)
-{
- struct ust_registry_channel *chan =
- caa_container_of(head, struct ust_registry_channel, rcu_head);
-
- if (chan->events) {
- lttng_ht_destroy(chan->events);
- }
-
- free(chan->ctx_fields);
- free(chan);
-}
-
-/*
- * Destroy every element of the registry and free the memory. This does NOT
- * free the registry pointer since it might not have been allocated before so
- * it's the caller responsability.
- */
-void ust_registry_channel_destroy(struct ust_registry_channel *chan, bool notify)
-{
- struct lttng_ht_iter iter;
- struct ust_registry_event *event;
- enum lttng_error_code cmd_ret;
-
- LTTNG_ASSERT(chan);
-
- if (notify) {
- cmd_ret = notification_thread_command_remove_channel(
- the_notification_thread_handle,
- chan->consumer_key, LTTNG_DOMAIN_UST);
- if (cmd_ret != LTTNG_OK) {
- ERR("Failed to remove channel from notification thread");
- }
- }
-
- if (chan->events) {
- rcu_read_lock();
- /* Destroy all event associated with this registry. */
- cds_lfht_for_each_entry(
- chan->events->ht, &iter.iter, event, node.node) {
- /* Delete the node from the ht and free it. */
- ust_registry_destroy_event(chan, event);
- }
- rcu_read_unlock();
- }
- call_rcu(&chan->rcu_head, destroy_channel_rcu);
-}
-
-/*
- * Initialize registry with default values.
- */
-int ust_registry_channel_add(ust_registry_session *session,
- uint64_t key)
-{
- int ret = 0;
- struct ust_registry_channel *chan;
-
- LTTNG_ASSERT(session);
-
- chan = zmalloc<ust_registry_channel>();
- if (!chan) {
- PERROR("zmalloc ust registry channel");
- ret = -ENOMEM;
- goto error_alloc;
- }
-
- chan->events = lttng_ht_new(0, LTTNG_HT_TYPE_STRING);
- if (!chan->events) {
- ret = -ENOMEM;
- goto error;
- }
-
- /* Set custom match function. */
- chan->events->match_fct = ht_match_event;
- chan->events->hash_fct = ht_hash_event;
-
- /*
- * Assign a channel ID right now since the event notification comes
- * *before* the channel notify so the ID needs to be set at this point so
- * the metadata can be dumped for that event.
- */
- if (ust_registry_is_max_id(session->_used_channel_id)) {
- ret = -1;
- goto error;
- }
- chan->chan_id = ust_registry_get_next_chan_id(session);
-
- rcu_read_lock();
- lttng_ht_node_init_u64(&chan->node, key);
- lttng_ht_add_unique_u64(session->_channels.get(), &chan->node);
- rcu_read_unlock();
-
- return 0;
-
-error:
- ust_registry_channel_destroy(chan, false);
-error_alloc:
- return ret;
-}
-
-/*
- * Find a channel in the given registry. RCU read side lock MUST be acquired
- * before calling this function and as long as the event reference is kept by
- * the caller.
- *
- * On success, the pointer is returned else NULL.
- */
-struct ust_registry_channel *ust_registry_channel_find(
- ust_registry_session *session, uint64_t key)
-{
- struct lttng_ht_node_u64 *node;
- struct lttng_ht_iter iter;
- struct ust_registry_channel *chan = NULL;
-
- LTTNG_ASSERT(session);
- LTTNG_ASSERT(session->_channels);
- ASSERT_RCU_READ_LOCKED();
-
- DBG3("UST registry channel finding key %" PRIu64, key);
-
- lttng_ht_lookup(session->_channels.get(), &key, &iter);
- node = lttng_ht_iter_get_node_u64(&iter);
- if (!node) {
- goto end;
- }
- chan = caa_container_of(node, struct ust_registry_channel, node);
-
-end:
- return chan;
-}
-
-/*
- * Remove channel using key from registry and free memory.
- */
-void ust_registry_channel_del_free(ust_registry_session *session,
- uint64_t key, bool notif)
-{
- struct lttng_ht_iter iter;
- struct ust_registry_channel *chan;
- int ret;
-
- LTTNG_ASSERT(session);
-
- rcu_read_lock();
- chan = ust_registry_channel_find(session, key);
- if (!chan) {
- rcu_read_unlock();
- goto end;
- }
-
- iter.iter.node = &chan->node.node;
- ret = lttng_ht_del(session->_channels.get(), &iter);
- LTTNG_ASSERT(!ret);
- rcu_read_unlock();
- ust_registry_channel_destroy(chan, notif);
-
-end:
- return;
-}
-
-ust_registry_session *ust_registry_session_per_uid_create(uint32_t bits_per_long,
- uint32_t uint8_t_alignment,
- uint32_t uint16_t_alignment,
- uint32_t uint32_t_alignment,
- uint32_t uint64_t_alignment,
- uint32_t long_alignment,
- int byte_order,