Clean-up: sessiond: remove left-over code
[lttng-tools.git] / src / bin / lttng-sessiond / ust-registry-channel.cpp
CommitLineData
d7bfb9b0
JG
1/*
2 * Copyright (C) 2022 Jérémie Galarneau <jeremie.galarneau@efficios.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 */
7
8#include "ust-registry-channel.hpp"
9#include "ust-app.hpp"
10#include "ust-registry-event.hpp"
11
12#include <common/error.hpp>
13#include <common/exception.hpp>
14#include <common/hashtable/utils.hpp>
15#include <common/make-unique-wrapper.hpp>
16#include <common/urcu.hpp>
17
18namespace lst = lttng::sessiond::trace;
19namespace lsu = lttng::sessiond::ust;
20
21namespace {
22bool is_max_event_id(uint32_t id)
23{
24 return id == UINT32_MAX;
25}
26
27unsigned long ht_hash_event(const void *_key, unsigned long seed)
28{
29 uint64_t hashed_key;
30 const lttng::sessiond::ust::registry_event *key =
31 (lttng::sessiond::ust::registry_event *) _key;
32
33 LTTNG_ASSERT(key);
34
35 hashed_key = (uint64_t) hash_key_str(key->name.c_str(), seed);
36
37 return hash_key_u64(&hashed_key, seed);
38}
39
40/*
41 * Hash table match function for event in the registry.
42 */
43int ht_match_event(struct cds_lfht_node *node, const void *_key)
44{
45 const lttng::sessiond::ust::registry_event *key;
46 lttng::sessiond::ust::registry_event *event;
47
48 LTTNG_ASSERT(node);
49 LTTNG_ASSERT(_key);
50
f139a4f9 51 event = lttng::utils::container_of(node, &lttng::sessiond::ust::registry_event::_node);
d7bfb9b0
JG
52 key = (lttng::sessiond::ust::registry_event *) _key;
53
54 /* It has to be a perfect match. First, compare the event names. */
55 if (event->name != key->name) {
56 goto no_match;
57 }
58
59 /* Compare log levels. */
60 if (event->log_level != key->log_level) {
61 goto no_match;
62 }
63
64 /* Compare the arrays of fields. */
65 if (*event->payload != *key->payload) {
66 goto no_match;
67 }
68
69 /* Compare model URI. */
70 if (event->model_emf_uri != key->model_emf_uri) {
71 goto no_match;
72 }
73
74 /* Match */
75 return 1;
76
77no_match:
78 return 0;
79}
80}; /* namespace */
81
82lsu::registry_channel::registry_channel(unsigned int channel_id,
83 lsu::registry_channel::registered_listener_fn channel_registered_listener,
84 lsu::registry_channel::event_added_listener_fn event_added_listener) :
85 lst::stream_class(channel_id, lst::stream_class::header_type::LARGE),
86 _key{-1ULL},
87 _consumer_key{-1ULL},
d7bfb9b0
JG
88 _next_event_id{0},
89 _is_registered_listener{channel_registered_listener},
90 _event_added_listener{event_added_listener},
91 _is_registered{false}
92{
93 _events = lttng_ht_new(0, LTTNG_HT_TYPE_STRING);
94 if (!_events) {
95 LTTNG_THROW_POSIX("Failed to allocate urcu events hash table", ENOMEM);
96 }
97
98 /* Set custom match function. */
99 _events->match_fct = ht_match_event;
100 _events->hash_fct = ht_hash_event;
36038679
JG
101
102 _rcu_head = {};
103 /*
104 * Node's key is initialized by the channel's parent session. Its value is irrelevant to the
105 * channel object itself.
106 */
107 _node = {};
d7bfb9b0
JG
108}
109
110void lsu::registry_channel::add_event(
111 int session_objd,
112 int channel_objd,
113 std::string name,
114 std::string signature,
115 std::vector<lst::field::cuptr> event_fields,
116 int loglevel_value,
117 nonstd::optional<std::string> model_emf_uri,
118 lttng_buffer_type buffer_type,
119 const ust_app& app,
120 uint32_t& out_event_id)
121{
122 uint32_t event_id;
123 struct cds_lfht_node *nptr;
124 lttng::urcu::read_lock_guard read_lock_guard;
125
126 /*
127 * This should not happen but since it comes from the UST tracer, an
128 * external party, don't assert and simply validate values.
129 */
130 if (session_objd < 0) {
131 LTTNG_THROW_INVALID_ARGUMENT_ERROR(fmt::format(
132 "Invalid session object descriptor provided by application: session descriptor = {}, app = {}",
133 session_objd, app));
134 }
135
136 if (channel_objd < 0) {
137 LTTNG_THROW_INVALID_ARGUMENT_ERROR(fmt::format(
138 "Invalid channel object descriptor provided by application: channel descriptor = {}, app = {}",
139 channel_objd, app));
140 }
141
142 /* Check if we've reached the maximum possible id. */
143 if (is_max_event_id(_next_event_id)) {
144 LTTNG_THROW_ERROR(fmt::format(
145 "Failed to allocate new event id (id would overflow): app = {}",
146 app));
147 }
148
149 auto event = lttng::make_unique_wrapper<lsu::registry_event, registry_event_destroy>(
150 new lsu::registry_event(_next_event_id, id, session_objd, channel_objd,
151 std::move(name), std::move(signature),
152 std::move(event_fields), loglevel_value,
153 std::move(model_emf_uri)));
154
155 DBG3("%s", fmt::format("UST registry creating event: event = {}", *event).c_str());
156
157 /*
158 * This is an add unique with a custom match function for event. The node
159 * are matched using the event name and signature.
160 */
161 nptr = cds_lfht_add_unique(_events->ht, _events->hash_fct(event.get(), lttng_ht_seed),
f139a4f9
JG
162 _events->match_fct, event.get(), &event->_node);
163 if (nptr != &event->_node) {
d7bfb9b0
JG
164 if (buffer_type == LTTNG_BUFFER_PER_UID) {
165 /*
166 * This is normal, we just have to send the event id of the
167 * returned node.
168 */
f139a4f9
JG
169 const auto existing_event = lttng::utils::container_of(
170 nptr, &lttng::sessiond::ust::registry_event::_node);
d7bfb9b0
JG
171 event_id = existing_event->id;
172 } else {
173 LTTNG_THROW_INVALID_ARGUMENT_ERROR(fmt::format(
174 "UST registry create event add unique failed for event: event = {}",
175 *event));
176 }
177 } else {
178 const auto& event_ref = *event;
179
180 /* Ownership transferred to _events hash table. */
181 event.release();
182
183 /* Request next event id if the node was successfully added. */
184 event_id = event_ref.id;
185
186 /*
187 * Only increment the next id here since we don't want to waste an ID when the event
188 * matches an existing one.
189 */
190 _next_event_id++;
191 _event_added_listener(*this, event_ref);
192 }
193
194 out_event_id = event_id;
195}
196
197lsu::registry_channel::~registry_channel()
198{
199 lttng_ht_destroy(_events);
200}
201
202const lttng::sessiond::trace::type& lsu::registry_channel::get_context() const
203{
204 LTTNG_ASSERT(_is_registered);
205 return lst::stream_class::get_context();
206}
207
208void lsu::registry_channel::set_context(lttng::sessiond::trace::type::cuptr context)
209{
210 /* Must only be set once, on the first channel registration provided by an application. */
211 LTTNG_ASSERT(!_context);
212 _context = std::move(context);
213}
214
215bool lsu::registry_channel::is_registered() const
216{
217 return _is_registered;
218}
219
220void lsu::registry_channel::set_as_registered()
221{
222 if (!_is_registered) {
223 _is_registered = true;
224 _is_registered_listener(*this);
225 }
226}
227
228void lsu::registry_channel::_accept_on_event_classes(
229 lttng::sessiond::trace::trace_class_visitor& visitor) const
230{
231 std::vector<const lttng::sessiond::ust::registry_event *> sorted_event_classes;
232
233 {
234 lttng::urcu::read_lock_guard read_lock_guard;
235 struct lttng_ht_iter iter;
236 const lttng::sessiond::ust::registry_event *event;
237
238 DIAGNOSTIC_PUSH
239 DIAGNOSTIC_IGNORE_INVALID_OFFSETOF
f139a4f9 240 cds_lfht_for_each_entry(_events->ht, &iter.iter, event, _node) {
d7bfb9b0
JG
241 sorted_event_classes.emplace_back(event);
242 }
243 DIAGNOSTIC_POP
244 }
245
246 std::sort(sorted_event_classes.begin(), sorted_event_classes.end(),
247 [](const lttng::sessiond::ust::registry_event *a,
248 const lttng::sessiond::ust::registry_event *b) {
249 return a->id < b->id;
250 });
251
252 for (const auto event : sorted_event_classes) {
253 event->accept(visitor);
254 }
255}
This page took 0.031539 seconds and 4 git commands to generate.