ctf plugin: notif iter: use "borrow" functions for metadata where possible
[babeltrace.git] / lib / ctf-ir / stream-class.c
1 /*
2 * stream-class.c
3 *
4 * Babeltrace CTF IR - Stream Class
5 *
6 * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
7 *
8 * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
9 *
10 * Permission is hereby granted, free of charge, to any person obtaining a copy
11 * of this software and associated documentation files (the "Software"), to deal
12 * in the Software without restriction, including without limitation the rights
13 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 * copies of the Software, and to permit persons to whom the Software is
15 * furnished to do so, subject to the following conditions:
16 *
17 * The above copyright notice and this permission notice shall be included in
18 * all copies or substantial portions of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26 * SOFTWARE.
27 */
28
29 #define BT_LOG_TAG "STREAM-CLASS"
30 #include <babeltrace/lib-logging-internal.h>
31
32 #include <babeltrace/assert-pre-internal.h>
33 #include <babeltrace/ctf-ir/clock-class-internal.h>
34 #include <babeltrace/ctf-ir/event-class-internal.h>
35 #include <babeltrace/ctf-ir/field-types-internal.h>
36 #include <babeltrace/ctf-ir/fields-internal.h>
37 #include <babeltrace/ctf-ir/stream-class-internal.h>
38 #include <babeltrace/ctf-ir/validation-internal.h>
39 #include <babeltrace/ctf-ir/visitor-internal.h>
40 #include <babeltrace/ctf-ir/utils.h>
41 #include <babeltrace/ctf-ir/utils-internal.h>
42 #include <babeltrace/ref.h>
43 #include <babeltrace/compiler-internal.h>
44 #include <babeltrace/align-internal.h>
45 #include <babeltrace/endian-internal.h>
46 #include <babeltrace/assert-internal.h>
47 #include <inttypes.h>
48 #include <stdint.h>
49 #include <stdbool.h>
50
51 BT_HIDDEN
52 int bt_stream_class_common_initialize(struct bt_stream_class_common *stream_class,
53 const char *name, bt_object_release_func release_func)
54 {
55 BT_LOGD("Initializing common stream class object: name=\"%s\"", name);
56
57 bt_object_init(stream_class, release_func);
58 stream_class->name = g_string_new(name);
59 stream_class->event_classes = g_ptr_array_new_with_free_func(
60 (GDestroyNotify) bt_object_release);
61 if (!stream_class->event_classes) {
62 BT_LOGE_STR("Failed to allocate a GPtrArray.");
63 goto error;
64 }
65
66 stream_class->event_classes_ht = g_hash_table_new_full(g_int64_hash,
67 g_int64_equal, g_free, NULL);
68 if (!stream_class->event_classes_ht) {
69 BT_LOGE_STR("Failed to allocate a GHashTable.");
70 goto error;
71 }
72
73 BT_LOGD("Initialized common stream class object: addr=%p, name=\"%s\"",
74 stream_class, name);
75 return 0;
76
77 error:
78 return -1;
79 }
80
81 BT_HIDDEN
82 void bt_stream_class_common_finalize(struct bt_stream_class_common *stream_class)
83 {
84 BT_LOGD("Finalizing common stream class: addr=%p, name=\"%s\", id=%" PRId64,
85 stream_class, bt_stream_class_common_get_name(stream_class),
86 bt_stream_class_common_get_id(stream_class));
87 bt_put(stream_class->clock_class);
88
89 if (stream_class->event_classes_ht) {
90 g_hash_table_destroy(stream_class->event_classes_ht);
91 }
92 if (stream_class->event_classes) {
93 BT_LOGD_STR("Destroying event classes.");
94 g_ptr_array_free(stream_class->event_classes, TRUE);
95 }
96
97 if (stream_class->name) {
98 g_string_free(stream_class->name, TRUE);
99 }
100
101 BT_LOGD_STR("Putting event header field type.");
102 bt_put(stream_class->event_header_field_type);
103 BT_LOGD_STR("Putting packet context field type.");
104 bt_put(stream_class->packet_context_field_type);
105 BT_LOGD_STR("Putting event context field type.");
106 bt_put(stream_class->event_context_field_type);
107 }
108
109 static
110 void bt_stream_class_destroy(struct bt_object *obj)
111 {
112 struct bt_stream_class *stream_class;
113
114 stream_class = (void *) obj;
115 BT_LOGD("Destroying stream class: addr=%p, name=\"%s\", id=%" PRId64,
116 stream_class, bt_stream_class_get_name(stream_class),
117 bt_stream_class_get_id(stream_class));
118 bt_stream_class_common_finalize(BT_TO_COMMON(stream_class));
119 g_free(stream_class);
120 }
121
122 struct bt_stream_class *bt_stream_class_create(const char *name)
123 {
124 struct bt_stream_class *stream_class = NULL;
125 int ret;
126
127 BT_LOGD("Creating stream class object: name=\"%s\"", name);
128 stream_class = g_new0(struct bt_stream_class, 1);
129 if (!stream_class) {
130 BT_LOGE_STR("Failed to allocate one stream class.");
131 goto error;
132 }
133
134 ret = bt_stream_class_common_initialize(BT_TO_COMMON(stream_class),
135 name, bt_stream_class_destroy);
136 if (ret) {
137 /* bt_stream_class_common_initialize() logs errors */
138 goto error;
139 }
140
141 BT_LOGD("Created stream class object: addr=%p, name=\"%s\"",
142 stream_class, name);
143 return stream_class;
144
145 error:
146 bt_put(stream_class);
147 return NULL;
148 }
149
150 struct bt_trace *bt_stream_class_borrow_trace(struct bt_stream_class *stream_class)
151 {
152 return BT_FROM_COMMON(bt_stream_class_common_borrow_trace(
153 BT_TO_COMMON(stream_class)));
154 }
155
156 const char *bt_stream_class_get_name(struct bt_stream_class *stream_class)
157 {
158 return bt_stream_class_common_get_name(BT_TO_COMMON(stream_class));
159 }
160
161 int bt_stream_class_set_name(struct bt_stream_class *stream_class,
162 const char *name)
163 {
164 return bt_stream_class_common_set_name(BT_TO_COMMON(stream_class),
165 name);
166 }
167
168 int64_t bt_stream_class_get_id(struct bt_stream_class *stream_class)
169 {
170 return bt_stream_class_common_get_id(BT_TO_COMMON(stream_class));
171 }
172
173 int bt_stream_class_set_id(struct bt_stream_class *stream_class, uint64_t id)
174 {
175 return bt_stream_class_common_set_id(BT_TO_COMMON(stream_class), id);
176 }
177
178 static
179 void event_class_exists(gpointer element, gpointer query)
180 {
181 struct bt_event_class_common *event_class_a = element;
182 struct search_query *search_query = query;
183 struct bt_event_class_common *event_class_b = search_query->value;
184 int64_t id_a, id_b;
185
186 if (search_query->value == element) {
187 search_query->found = 1;
188 goto end;
189 }
190
191 /*
192 * Two event classes cannot share the same ID in a given
193 * stream class.
194 */
195 id_a = bt_event_class_common_get_id(event_class_a);
196 id_b = bt_event_class_common_get_id(event_class_b);
197
198 if (id_a < 0 || id_b < 0) {
199 /* at least one ID is not set: will be automatically set later */
200 goto end;
201 }
202
203 if (id_a == id_b) {
204 BT_LOGW("Event class with this ID already exists in the stream class: "
205 "id=%" PRId64 ", name=\"%s\"",
206 id_a, bt_event_class_common_get_name(event_class_a));
207 search_query->found = 1;
208 goto end;
209 }
210
211 end:
212 return;
213 }
214
215 BT_HIDDEN
216 int bt_stream_class_common_add_event_class(
217 struct bt_stream_class_common *stream_class,
218 struct bt_event_class_common *event_class,
219 bt_validation_flag_copy_field_type_func copy_field_type_func)
220 {
221 int ret = 0;
222 int64_t *event_id = NULL;
223 struct bt_trace_common *trace = NULL;
224 struct bt_stream_class_common *old_stream_class = NULL;
225 struct bt_validation_output validation_output = { 0 };
226 struct bt_field_type_common *packet_header_type = NULL;
227 struct bt_field_type_common *packet_context_type = NULL;
228 struct bt_field_type_common *event_header_type = NULL;
229 struct bt_field_type_common *stream_event_ctx_type = NULL;
230 struct bt_field_type_common *event_context_type = NULL;
231 struct bt_field_type_common *event_payload_type = NULL;
232 const enum bt_validation_flag validation_flags =
233 BT_VALIDATION_FLAG_EVENT;
234 struct bt_clock_class *expected_clock_class = NULL;
235
236 BT_ASSERT(copy_field_type_func);
237
238 if (!stream_class || !event_class) {
239 BT_LOGW("Invalid parameter: stream class or event class is NULL: "
240 "stream-class-addr=%p, event-class-addr=%p",
241 stream_class, event_class);
242 ret = -1;
243 goto end;
244 }
245
246 BT_LOGD("Adding event class to stream class: "
247 "stream-class-addr=%p, stream-class-name=\"%s\", "
248 "stream-class-id=%" PRId64 ", event-class-addr=%p, "
249 "event-class-name=\"%s\", event-class-id=%" PRId64,
250 stream_class, bt_stream_class_common_get_name(stream_class),
251 bt_stream_class_common_get_id(stream_class),
252 event_class,
253 bt_event_class_common_get_name(event_class),
254 bt_event_class_common_get_id(event_class));
255 trace = bt_stream_class_common_borrow_trace(stream_class);
256
257 if (stream_class->frozen) {
258 /*
259 * We only check that the event class to be added has a
260 * single class which matches the stream class's
261 * expected clock class if the stream class is frozen.
262 * If it's not, then this event class is added "as is"
263 * and the validation will be performed when calling
264 * either bt_trace_add_stream_class() or
265 * bt_event_create(). This is because the stream class's
266 * field types (packet context, event header, event
267 * context) could change before the next call to one of
268 * those two functions.
269 */
270 expected_clock_class = bt_get(stream_class->clock_class);
271
272 /*
273 * At this point, `expected_clock_class` can be NULL,
274 * and bt_event_class_validate_single_clock_class()
275 * below can set it.
276 */
277 ret = bt_event_class_common_validate_single_clock_class(
278 event_class, &expected_clock_class);
279 if (ret) {
280 BT_LOGW("Event class contains a field type which is not "
281 "recursively mapped to its stream class's "
282 "expected clock class: "
283 "stream-class-addr=%p, "
284 "stream-class-id=%" PRId64 ", "
285 "stream-class-name=\"%s\", "
286 "expected-clock-class-addr=%p, "
287 "expected-clock-class-name=\"%s\"",
288 stream_class,
289 bt_stream_class_common_get_id(stream_class),
290 bt_stream_class_common_get_name(stream_class),
291 expected_clock_class,
292 expected_clock_class ?
293 bt_clock_class_get_name(expected_clock_class) :
294 NULL);
295 goto end;
296 }
297 }
298
299 event_id = g_new(int64_t, 1);
300 if (!event_id) {
301 BT_LOGE_STR("Failed to allocate one int64_t.");
302 ret = -1;
303 goto end;
304 }
305
306 /* Check for duplicate event classes */
307 struct search_query query = { .value = event_class, .found = 0 };
308 g_ptr_array_foreach(stream_class->event_classes, event_class_exists,
309 &query);
310 if (query.found) {
311 BT_LOGW_STR("Another event class part of this stream class has the same ID.");
312 ret = -1;
313 goto end;
314 }
315
316 old_stream_class = bt_event_class_common_borrow_stream_class(event_class);
317 if (old_stream_class) {
318 /* Event class is already associated to a stream class. */
319 BT_LOGW("Event class is already part of another stream class: "
320 "event-class-stream-class-addr=%p, "
321 "event-class-stream-class-name=\"%s\", "
322 "event-class-stream-class-id=%" PRId64,
323 old_stream_class,
324 bt_stream_class_common_get_name(old_stream_class),
325 bt_stream_class_common_get_id(old_stream_class));
326 ret = -1;
327 goto end;
328 }
329
330 if (trace) {
331 /*
332 * If the stream class is associated with a trace, then
333 * both those objects are frozen. Also, this event class
334 * is about to be frozen.
335 *
336 * Therefore the event class must be validated here.
337 * The trace and stream class should be valid at this
338 * point.
339 */
340 BT_ASSERT(trace->valid);
341 BT_ASSERT(stream_class->valid);
342 packet_header_type =
343 bt_trace_common_borrow_packet_header_field_type(trace);
344 packet_context_type =
345 bt_stream_class_common_borrow_packet_context_field_type(
346 stream_class);
347 event_header_type =
348 bt_stream_class_common_borrow_event_header_field_type(
349 stream_class);
350 stream_event_ctx_type =
351 bt_stream_class_common_borrow_event_context_field_type(
352 stream_class);
353 event_context_type =
354 bt_event_class_common_borrow_context_field_type(
355 event_class);
356 event_payload_type =
357 bt_event_class_common_borrow_payload_field_type(
358 event_class);
359 ret = bt_validate_class_types(
360 trace->environment, packet_header_type,
361 packet_context_type, event_header_type,
362 stream_event_ctx_type, event_context_type,
363 event_payload_type, trace->valid,
364 stream_class->valid, event_class->valid,
365 &validation_output, validation_flags,
366 copy_field_type_func);
367
368 if (ret) {
369 /*
370 * This means something went wrong during the
371 * validation process, not that the objects are
372 * invalid.
373 */
374 BT_LOGE("Failed to validate event class: ret=%d", ret);
375 goto end;
376 }
377
378 if ((validation_output.valid_flags & validation_flags) !=
379 validation_flags) {
380 /* Invalid event class */
381 BT_LOGW("Invalid trace, stream class, or event class: "
382 "valid-flags=0x%x",
383 validation_output.valid_flags);
384 ret = -1;
385 goto end;
386 }
387 }
388
389 /* Only set an event ID if none was explicitly set before */
390 *event_id = bt_event_class_common_get_id(event_class);
391 if (*event_id < 0) {
392 BT_LOGV("Event class has no ID: automatically setting it: "
393 "id=%" PRId64, stream_class->next_event_id);
394
395 if (bt_event_class_common_set_id(event_class,
396 stream_class->next_event_id)) {
397 BT_LOGE("Cannot set event class's ID: id=%" PRId64,
398 stream_class->next_event_id);
399 ret = -1;
400 goto end;
401 }
402 stream_class->next_event_id++;
403 *event_id = stream_class->next_event_id;
404 }
405
406 bt_object_set_parent(event_class, stream_class);
407
408 if (trace) {
409 /*
410 * At this point we know that the function will be
411 * successful. Therefore we can replace the event
412 * class's field types with what's in the validation
413 * output structure and mark this event class as valid.
414 */
415 bt_validation_replace_types(NULL, NULL, event_class,
416 &validation_output, validation_flags);
417 event_class->valid = 1;
418
419 /*
420 * Put what was not moved in
421 * bt_validation_replace_types().
422 */
423 bt_validation_output_put_types(&validation_output);
424 }
425
426 /* Add to the event classes of the stream class */
427 g_ptr_array_add(stream_class->event_classes, event_class);
428 g_hash_table_insert(stream_class->event_classes_ht, event_id,
429 event_class);
430 event_id = NULL;
431
432 /* Freeze the event class */
433 bt_event_class_common_freeze(event_class);
434
435 /*
436 * It is safe to set the stream class's unique clock class
437 * now if the stream class is frozen.
438 */
439 if (stream_class->frozen && expected_clock_class) {
440 BT_ASSERT(!stream_class->clock_class ||
441 stream_class->clock_class == expected_clock_class);
442 BT_MOVE(stream_class->clock_class, expected_clock_class);
443 }
444
445 BT_LOGD("Added event class to stream class: "
446 "stream-class-addr=%p, stream-class-name=\"%s\", "
447 "stream-class-id=%" PRId64 ", event-class-addr=%p, "
448 "event-class-name=\"%s\", event-class-id=%" PRId64,
449 stream_class, bt_stream_class_common_get_name(stream_class),
450 bt_stream_class_common_get_id(stream_class),
451 event_class,
452 bt_event_class_common_get_name(event_class),
453 bt_event_class_common_get_id(event_class));
454
455 end:
456 bt_validation_output_put_types(&validation_output);
457 bt_put(expected_clock_class);
458 g_free(event_id);
459 return ret;
460 }
461
462 int bt_stream_class_add_event_class(
463 struct bt_stream_class *stream_class,
464 struct bt_event_class *event_class)
465 {
466 struct bt_trace *trace;
467 int ret = 0;
468
469 if (!stream_class) {
470 BT_LOGW("Invalid parameter: stream class is NULL: "
471 "stream-class-addr=%p", stream_class);
472 ret = -1;
473 goto end;
474 }
475
476 trace = BT_FROM_COMMON(bt_stream_class_common_borrow_trace(
477 BT_TO_COMMON(stream_class)));
478 if (trace && trace->is_static) {
479 BT_LOGW("Invalid parameter: stream class's trace is static: "
480 "trace-addr=%p, trace-name=\"%s\"",
481 trace, bt_trace_get_name(trace));
482 ret = -1;
483 goto end;
484 }
485
486 ret = bt_stream_class_common_add_event_class(
487 BT_TO_COMMON(stream_class), BT_TO_COMMON(event_class),
488 (bt_validation_flag_copy_field_type_func) bt_field_type_copy);
489 if (ret) {
490 goto end;
491 }
492
493 /* Notifiy listeners of the trace's schema modification. */
494 if (trace) {
495 struct bt_visitor_object obj = { .object = event_class,
496 .type = BT_VISITOR_OBJECT_TYPE_EVENT_CLASS };
497
498 (void) bt_trace_object_modification(&obj, trace);
499 }
500
501 end:
502 return ret;
503 }
504
505 int64_t bt_stream_class_get_event_class_count(
506 struct bt_stream_class *stream_class)
507 {
508 return bt_stream_class_common_get_event_class_count(
509 BT_TO_COMMON(stream_class));
510 }
511
512 struct bt_event_class *bt_stream_class_borrow_event_class_by_index(
513 struct bt_stream_class *stream_class, uint64_t index)
514 {
515 return BT_FROM_COMMON(bt_stream_class_common_borrow_event_class_by_index(
516 BT_TO_COMMON(stream_class), index));
517 }
518
519 struct bt_event_class *bt_stream_class_borrow_event_class_by_id(
520 struct bt_stream_class *stream_class, uint64_t id)
521 {
522 return BT_FROM_COMMON(bt_stream_class_common_borrow_event_class_by_id(
523 BT_TO_COMMON(stream_class), id));
524 }
525
526 struct bt_field_type *bt_stream_class_borrow_packet_context_field_type(
527 struct bt_stream_class *stream_class)
528 {
529 return BT_FROM_COMMON(bt_stream_class_common_borrow_packet_context_field_type(
530 BT_TO_COMMON(stream_class)));
531 }
532
533 int bt_stream_class_set_packet_context_field_type(
534 struct bt_stream_class *stream_class,
535 struct bt_field_type *packet_context_type)
536 {
537 return bt_stream_class_common_set_packet_context_field_type(
538 BT_TO_COMMON(stream_class), (void *) packet_context_type);
539 }
540
541 struct bt_field_type *bt_stream_class_borrow_event_header_field_type(
542 struct bt_stream_class *stream_class)
543 {
544 return BT_FROM_COMMON(bt_stream_class_common_borrow_event_header_field_type(
545 BT_TO_COMMON(stream_class)));
546 }
547
548 int bt_stream_class_set_event_header_field_type(
549 struct bt_stream_class *stream_class,
550 struct bt_field_type *event_header_type)
551 {
552 return bt_stream_class_common_set_event_header_field_type(
553 BT_TO_COMMON(stream_class), (void *) event_header_type);
554 }
555
556 struct bt_field_type *bt_stream_class_borrow_event_context_field_type(
557 struct bt_stream_class *stream_class)
558 {
559 return BT_FROM_COMMON(bt_stream_class_common_borrow_event_context_field_type(
560 BT_TO_COMMON(stream_class)));
561 }
562
563 int bt_stream_class_set_event_context_field_type(
564 struct bt_stream_class *stream_class,
565 struct bt_field_type *event_context_type)
566 {
567 return bt_stream_class_common_set_event_context_field_type(
568 BT_TO_COMMON(stream_class), (void *) event_context_type);
569 }
570
571 static
572 int64_t get_event_class_count(void *element)
573 {
574 return bt_stream_class_get_event_class_count(
575 (struct bt_stream_class *) element);
576 }
577
578 static
579 void *get_event_class(void *element, int i)
580 {
581 return bt_stream_class_get_event_class_by_index(
582 (struct bt_stream_class *) element, i);
583 }
584
585 static
586 int visit_event_class(void *object, bt_visitor visitor,void *data)
587 {
588 struct bt_visitor_object obj = {
589 .object = object,
590 .type = BT_VISITOR_OBJECT_TYPE_EVENT_CLASS
591 };
592
593 return visitor(&obj, data);
594 }
595
596 BT_HIDDEN
597 int bt_stream_class_common_visit(struct bt_stream_class_common *stream_class,
598 bt_visitor visitor, void *data)
599 {
600 int ret;
601 struct bt_visitor_object obj = {
602 .object = stream_class,
603 .type = BT_VISITOR_OBJECT_TYPE_STREAM_CLASS
604 };
605
606 if (!stream_class || !visitor) {
607 BT_LOGW("Invalid parameter: stream class or visitor is NULL: "
608 "stream-class-addr=%p, visitor=%p",
609 stream_class, visitor);
610 ret = -1;
611 goto end;
612 }
613
614 ret = visitor_helper(&obj, get_event_class_count,
615 get_event_class,
616 visit_event_class, visitor, data);
617 BT_LOGV("visitor_helper() returned: ret=%d", ret);
618
619 end:
620 return ret;
621 }
622
623 int bt_stream_class_visit(struct bt_stream_class *stream_class,
624 bt_visitor visitor, void *data)
625 {
626 return bt_stream_class_common_visit(BT_FROM_COMMON(stream_class),
627 visitor, data);
628 }
629
630 BT_HIDDEN
631 void bt_stream_class_common_freeze(struct bt_stream_class_common *stream_class)
632 {
633 if (!stream_class || stream_class->frozen) {
634 return;
635 }
636
637 BT_LOGD("Freezing stream class: addr=%p, name=\"%s\", id=%" PRId64,
638 stream_class, bt_stream_class_common_get_name(stream_class),
639 bt_stream_class_common_get_id(stream_class));
640 stream_class->frozen = 1;
641 bt_field_type_common_freeze(stream_class->event_header_field_type);
642 bt_field_type_common_freeze(stream_class->packet_context_field_type);
643 bt_field_type_common_freeze(stream_class->event_context_field_type);
644 bt_clock_class_freeze(stream_class->clock_class);
645 }
646
647 void bt_stream_class_freeze(struct bt_stream_class *stream_class)
648 {
649 bt_stream_class_common_freeze(BT_TO_COMMON(stream_class));
650 }
651
652 BT_HIDDEN
653 int bt_stream_class_common_validate_single_clock_class(
654 struct bt_stream_class_common *stream_class,
655 struct bt_clock_class **expected_clock_class)
656 {
657 int ret;
658 uint64_t i;
659
660 BT_ASSERT(stream_class);
661 BT_ASSERT(expected_clock_class);
662 ret = bt_field_type_common_validate_single_clock_class(
663 stream_class->packet_context_field_type,
664 expected_clock_class);
665 if (ret) {
666 BT_LOGW("Stream class's packet context field type "
667 "is not recursively mapped to the "
668 "expected clock class: "
669 "stream-class-addr=%p, "
670 "stream-class-name=\"%s\", "
671 "stream-class-id=%" PRId64 ", "
672 "ft-addr=%p",
673 stream_class,
674 bt_stream_class_common_get_name(stream_class),
675 stream_class->id,
676 stream_class->packet_context_field_type);
677 goto end;
678 }
679
680 ret = bt_field_type_common_validate_single_clock_class(
681 stream_class->event_header_field_type,
682 expected_clock_class);
683 if (ret) {
684 BT_LOGW("Stream class's event header field type "
685 "is not recursively mapped to the "
686 "expected clock class: "
687 "stream-class-addr=%p, "
688 "stream-class-name=\"%s\", "
689 "stream-class-id=%" PRId64 ", "
690 "ft-addr=%p",
691 stream_class,
692 bt_stream_class_common_get_name(stream_class),
693 stream_class->id,
694 stream_class->event_header_field_type);
695 goto end;
696 }
697
698 ret = bt_field_type_common_validate_single_clock_class(
699 stream_class->event_context_field_type,
700 expected_clock_class);
701 if (ret) {
702 BT_LOGW("Stream class's event context field type "
703 "is not recursively mapped to the "
704 "expected clock class: "
705 "stream-class-addr=%p, "
706 "stream-class-name=\"%s\", "
707 "stream-class-id=%" PRId64 ", "
708 "ft-addr=%p",
709 stream_class,
710 bt_stream_class_common_get_name(stream_class),
711 stream_class->id,
712 stream_class->event_context_field_type);
713 goto end;
714 }
715
716 for (i = 0; i < stream_class->event_classes->len; i++) {
717 struct bt_event_class_common *event_class =
718 g_ptr_array_index(stream_class->event_classes, i);
719
720 BT_ASSERT(event_class);
721 ret = bt_event_class_common_validate_single_clock_class(
722 event_class, expected_clock_class);
723 if (ret) {
724 BT_LOGW("Stream class's event class contains a "
725 "field type which is not recursively mapped to "
726 "the expected clock class: "
727 "stream-class-addr=%p, "
728 "stream-class-name=\"%s\", "
729 "stream-class-id=%" PRId64,
730 stream_class,
731 bt_stream_class_common_get_name(stream_class),
732 stream_class->id);
733 goto end;
734 }
735 }
736
737 end:
738 return ret;
739 }
This page took 0.055956 seconds and 4 git commands to generate.