Force usage of assert() condition when NDEBUG is defined
[lttng-tools.git] / src / common / conditions / condition.c
CommitLineData
a58c490f 1/*
ab5be9fa 2 * Copyright (C) 2017 Jérémie Galarneau <jeremie.galarneau@efficios.com>
a58c490f 3 *
ab5be9fa 4 * SPDX-License-Identifier: LGPL-2.1-only
a58c490f 5 *
a58c490f
JG
6 */
7
6a751b95
JR
8#include <common/buffer-view.h>
9#include <common/dynamic-buffer.h>
10#include <common/error.h>
11#include <common/macros.h>
12#include <common/mi-lttng.h>
a58c490f 13#include <lttng/condition/buffer-usage-internal.h>
6a751b95 14#include <lttng/condition/condition-internal.h>
670a26e4 15#include <lttng/condition/event-rule-matches-internal.h>
e8360425 16#include <lttng/condition/session-consumed-size-internal.h>
c19092cd 17#include <lttng/condition/session-rotation-internal.h>
6a751b95 18#include <lttng/error-query-internal.h>
a58c490f 19#include <stdbool.h>
a58c490f
JG
20
21enum lttng_condition_type lttng_condition_get_type(
22 const struct lttng_condition *condition)
23{
24 return condition ? condition->type : LTTNG_CONDITION_TYPE_UNKNOWN;
25}
26
27void lttng_condition_destroy(struct lttng_condition *condition)
4655b864
JR
28{
29 lttng_condition_put(condition);
30}
31
32static void condition_destroy_ref(struct urcu_ref *ref)
33{
34 struct lttng_condition *condition =
35 container_of(ref, struct lttng_condition, ref);
36
37 condition->destroy(condition);
38}
39
40LTTNG_HIDDEN
41void lttng_condition_get(struct lttng_condition *condition)
42{
43 urcu_ref_get(&condition->ref);
44}
45
46LTTNG_HIDDEN
47void lttng_condition_put(struct lttng_condition *condition)
a58c490f
JG
48{
49 if (!condition) {
50 return;
51 }
52
a0377dfe 53 LTTNG_ASSERT(condition->destroy);
4655b864 54 urcu_ref_put(&condition->ref, condition_destroy_ref);
a58c490f
JG
55}
56
4655b864 57
a58c490f
JG
58LTTNG_HIDDEN
59bool lttng_condition_validate(const struct lttng_condition *condition)
60{
61 bool valid;
62
63 if (!condition) {
64 valid = false;
65 goto end;
66 }
67
68 if (!condition->validate) {
69 /* Sub-class guarantees that it can never be invalid. */
70 valid = true;
71 goto end;
72 }
73
74 valid = condition->validate(condition);
75end:
76 return valid;
77}
78
79LTTNG_HIDDEN
3647288f 80int lttng_condition_serialize(const struct lttng_condition *condition,
c0a66c84 81 struct lttng_payload *payload)
a58c490f 82{
3647288f 83 int ret;
c0a66c84 84 struct lttng_condition_comm condition_comm = {};
a58c490f
JG
85
86 if (!condition) {
87 ret = -1;
88 goto end;
89 }
90
3647288f
JG
91 condition_comm.condition_type = (int8_t) condition->type;
92
c0a66c84 93 ret = lttng_dynamic_buffer_append(&payload->buffer, &condition_comm,
3647288f
JG
94 sizeof(condition_comm));
95 if (ret) {
96 goto end;
a58c490f
JG
97 }
98
c0a66c84 99 ret = condition->serialize(condition, payload);
3647288f 100 if (ret) {
a58c490f
JG
101 goto end;
102 }
a58c490f
JG
103end:
104 return ret;
105}
106
107LTTNG_HIDDEN
108bool lttng_condition_is_equal(const struct lttng_condition *a,
109 const struct lttng_condition *b)
110{
111 bool is_equal = false;
112
113 if (!a || !b) {
114 goto end;
115 }
116
117 if (a->type != b->type) {
118 goto end;
119 }
120
6c2fe319
JG
121 if (a == b) {
122 is_equal = true;
123 goto end;
124 }
125
a58c490f
JG
126 is_equal = a->equal ? a->equal(a, b) : true;
127end:
128 return is_equal;
129}
130
131LTTNG_HIDDEN
c0a66c84
JG
132ssize_t lttng_condition_create_from_payload(
133 struct lttng_payload_view *view,
a58c490f
JG
134 struct lttng_condition **condition)
135{
136 ssize_t ret, condition_size = 0;
c0a66c84 137 condition_create_from_payload_cb create_from_payload = NULL;
3e6e0df2
JG
138 const struct lttng_condition_comm *condition_comm;
139 const struct lttng_payload_view condition_comm_view =
140 lttng_payload_view_from_view(
141 view, 0, sizeof(*condition_comm));
a58c490f 142
c0a66c84 143 if (!view || !condition) {
a58c490f
JG
144 ret = -1;
145 goto end;
146 }
147
3e6e0df2
JG
148 if (!lttng_payload_view_is_valid(&condition_comm_view)) {
149 /* Payload not large enough to contain the header. */
150 ret = -1;
151 goto end;
152 }
153
a58c490f 154 DBG("Deserializing condition from buffer");
3e6e0df2 155 condition_comm = (typeof(condition_comm)) condition_comm_view.buffer.data;
a58c490f
JG
156 condition_size += sizeof(*condition_comm);
157
158 switch ((enum lttng_condition_type) condition_comm->condition_type) {
159 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW:
c0a66c84 160 create_from_payload = lttng_condition_buffer_usage_low_create_from_payload;
a58c490f
JG
161 break;
162 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH:
c0a66c84 163 create_from_payload = lttng_condition_buffer_usage_high_create_from_payload;
a58c490f 164 break;
e8360425 165 case LTTNG_CONDITION_TYPE_SESSION_CONSUMED_SIZE:
c0a66c84 166 create_from_payload = lttng_condition_session_consumed_size_create_from_payload;
e8360425 167 break;
c19092cd 168 case LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING:
c0a66c84 169 create_from_payload = lttng_condition_session_rotation_ongoing_create_from_payload;
c19092cd
JG
170 break;
171 case LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED:
c0a66c84 172 create_from_payload = lttng_condition_session_rotation_completed_create_from_payload;
c19092cd 173 break;
8dbb86b8
JR
174 case LTTNG_CONDITION_TYPE_EVENT_RULE_MATCHES:
175 create_from_payload =
176 lttng_condition_event_rule_matches_create_from_payload;
683d081a 177 break;
a58c490f
JG
178 default:
179 ERR("Attempted to create condition of unknown type (%i)",
180 (int) condition_comm->condition_type);
181 ret = -1;
182 goto end;
183 }
184
c0a66c84
JG
185 if (create_from_payload) {
186 struct lttng_payload_view condition_view =
187 lttng_payload_view_from_view(view,
a58c490f
JG
188 sizeof(*condition_comm), -1);
189
c0a66c84 190 ret = create_from_payload(&condition_view, condition);
a58c490f
JG
191 if (ret < 0) {
192 goto end;
193 }
194 condition_size += ret;
195
196 } else {
197 abort();
198 }
199
200 ret = condition_size;
201end:
202 return ret;
203}
204
205LTTNG_HIDDEN
206void lttng_condition_init(struct lttng_condition *condition,
207 enum lttng_condition_type type)
208{
209 condition->type = type;
4655b864 210 urcu_ref_init(&condition->ref);
a58c490f 211}
0de2479d
SM
212
213LTTNG_HIDDEN
214const char *lttng_condition_type_str(enum lttng_condition_type type)
215{
216 switch (type) {
217 case LTTNG_CONDITION_TYPE_UNKNOWN:
218 return "unknown";
219
220 case LTTNG_CONDITION_TYPE_SESSION_CONSUMED_SIZE:
221 return "session consumed size";
222
223 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH:
224 return "buffer usage high";
225
226 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW:
227 return "buffer usage low";
228
229 case LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING:
230 return "session rotation ongoing";
231
232 case LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED:
233 return "session rotation completed";
234
8dbb86b8 235 case LTTNG_CONDITION_TYPE_EVENT_RULE_MATCHES:
8c1d25ff 236 return "event rule matches";
0de2479d
SM
237
238 default:
239 return "???";
240 }
241}
6a751b95
JR
242
243LTTNG_HIDDEN
244enum lttng_error_code lttng_condition_mi_serialize(
245 const struct lttng_trigger *trigger,
246 const struct lttng_condition *condition,
247 struct mi_writer *writer,
248 const struct mi_lttng_error_query_callbacks *error_query_callbacks)
249{
250 int ret;
251 enum lttng_error_code ret_code;
252 struct lttng_error_query_results *error_query_results = NULL;
253
a0377dfe
FD
254 LTTNG_ASSERT(condition);
255 LTTNG_ASSERT(writer);
256 LTTNG_ASSERT(condition->mi_serialize);
6a751b95
JR
257
258 /* Open condition element. */
259 ret = mi_lttng_writer_open_element(writer, mi_lttng_element_condition);
260 if (ret) {
261 goto mi_error;
262 }
263
264 /* Serialize underlying condition. */
265 ret_code = condition->mi_serialize(condition, writer);
266 if (ret_code != LTTNG_OK) {
267 goto end;
268 }
269
270 /* Serialize error query results for the action. */
271 if (error_query_callbacks && error_query_callbacks->action_cb) {
272 ret_code = error_query_callbacks->condition_cb(
273 trigger, &error_query_results);
274 if (ret_code != LTTNG_OK) {
275 goto end;
276 }
277
278 ret_code = lttng_error_query_results_mi_serialize(
279 error_query_results, writer);
280 if (ret_code != LTTNG_OK) {
281 goto end;
282 }
283 }
284
285 /* Close condition element. */
286 ret = mi_lttng_writer_close_element(writer);
287 if (ret) {
288 goto mi_error;
289 }
290
291 ret_code = LTTNG_OK;
292 goto end;
293
294mi_error:
295 ret_code = LTTNG_ERR_MI_IO_FAIL;
296end:
297 lttng_error_query_results_destroy(error_query_results);
298 return ret_code;
299}
This page took 0.049046 seconds and 4 git commands to generate.