2 * Copyright 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com>
4 * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 #define BT_LOG_TAG "COMP-CLASS"
26 #include <babeltrace/lib-logging-internal.h>
28 #include <babeltrace/compiler-internal.h>
29 #include <babeltrace/graph/component-class.h>
30 #include <babeltrace/graph/component-class-const.h>
31 #include <babeltrace/graph/component-class-source.h>
32 #include <babeltrace/graph/component-class-source-const.h>
33 #include <babeltrace/graph/component-class-filter.h>
34 #include <babeltrace/graph/component-class-filter-const.h>
35 #include <babeltrace/graph/component-class-sink.h>
36 #include <babeltrace/graph/component-class-sink-const.h>
37 #include <babeltrace/graph/component-class-internal.h>
38 #include <babeltrace/object.h>
39 #include <babeltrace/types.h>
40 #include <babeltrace/assert-internal.h>
41 #include <babeltrace/assert-pre-internal.h>
44 #define BT_ASSERT_PRE_COMP_CLS_HOT(_cc) \
45 BT_ASSERT_PRE_HOT(((const struct bt_component_class *) (_cc)), \
46 "Component class", ": %!+C", (_cc))
49 void destroy_component_class(struct bt_object
*obj
)
51 struct bt_component_class
*class;
55 class = container_of(obj
, struct bt_component_class
, base
);
57 BT_LIB_LOGD("Destroying component class: %!+C", class);
59 /* Call destroy listeners in reverse registration order */
60 for (i
= class->destroy_listeners
->len
- 1; i
>= 0; i
--) {
61 struct bt_component_class_destroy_listener
*listener
=
62 &g_array_index(class->destroy_listeners
,
63 struct bt_component_class_destroy_listener
,
66 BT_LOGD("Calling destroy listener: func-addr=%p, data-addr=%p",
67 listener
->func
, listener
->data
);
68 listener
->func(class, listener
->data
);
72 g_string_free(class->name
, TRUE
);
76 if (class->description
) {
77 g_string_free(class->description
, TRUE
);
78 class->description
= NULL
;
82 g_string_free(class->help
, TRUE
);
86 if (class->destroy_listeners
) {
87 g_array_free(class->destroy_listeners
, TRUE
);
88 class->destroy_listeners
= NULL
;
95 int bt_component_class_init(struct bt_component_class
*class,
96 enum bt_component_class_type type
, const char *name
)
100 bt_object_init_shared(&class->base
, destroy_component_class
);
102 class->name
= g_string_new(name
);
104 BT_LOGE_STR("Failed to allocate a GString.");
108 class->description
= g_string_new(NULL
);
109 if (!class->description
) {
110 BT_LOGE_STR("Failed to allocate a GString.");
114 class->help
= g_string_new(NULL
);
116 BT_LOGE_STR("Failed to allocate a GString.");
120 class->destroy_listeners
= g_array_new(FALSE
, TRUE
,
121 sizeof(struct bt_component_class_destroy_listener
));
122 if (!class->destroy_listeners
) {
123 BT_LOGE_STR("Failed to allocate a GArray.");
130 BT_OBJECT_PUT_REF_AND_RESET(class);
137 struct bt_component_class_source
*bt_component_class_source_create(
139 bt_component_class_source_notification_iterator_next_method method
)
141 struct bt_component_class_source
*source_class
= NULL
;
144 BT_ASSERT_PRE_NON_NULL(name
, "Name");
145 BT_ASSERT_PRE_NON_NULL(method
, "Notification iterator next method");
146 BT_LOGD("Creating source component class: "
147 "name=\"%s\", notif-iter-next-method-addr=%p",
149 source_class
= g_new0(struct bt_component_class_source
, 1);
151 BT_LOGE_STR("Failed to allocate one source component class.");
155 /* bt_component_class_init() logs errors */
156 ret
= bt_component_class_init(&source_class
->parent
,
157 BT_COMPONENT_CLASS_TYPE_SOURCE
, name
);
160 * If bt_component_class_init() fails, the component
161 * class is put, therefore its memory is already
168 source_class
->methods
.notif_iter_next
= method
;
169 BT_LIB_LOGD("Created source component class: %!+C", source_class
);
172 return (void *) source_class
;
175 struct bt_component_class_filter
*bt_component_class_filter_create(
177 bt_component_class_filter_notification_iterator_next_method method
)
179 struct bt_component_class_filter
*filter_class
= NULL
;
182 BT_ASSERT_PRE_NON_NULL(name
, "Name");
183 BT_ASSERT_PRE_NON_NULL(method
, "Notification iterator next method");
184 BT_LOGD("Creating filter component class: "
185 "name=\"%s\", notif-iter-next-method-addr=%p",
187 filter_class
= g_new0(struct bt_component_class_filter
, 1);
189 BT_LOGE_STR("Failed to allocate one filter component class.");
193 /* bt_component_class_init() logs errors */
194 ret
= bt_component_class_init(&filter_class
->parent
,
195 BT_COMPONENT_CLASS_TYPE_FILTER
, name
);
198 * If bt_component_class_init() fails, the component
199 * class is put, therefore its memory is already
206 filter_class
->methods
.notif_iter_next
= method
;
207 BT_LIB_LOGD("Created filter component class: %!+C", filter_class
);
210 return (void *) filter_class
;
213 struct bt_component_class_sink
*bt_component_class_sink_create(
214 const char *name
, bt_component_class_sink_consume_method method
)
216 struct bt_component_class_sink
*sink_class
= NULL
;
219 BT_ASSERT_PRE_NON_NULL(name
, "Name");
220 BT_ASSERT_PRE_NON_NULL(method
, "Consume next method");
221 BT_LOGD("Creating sink component class: "
222 "name=\"%s\", consume-method-addr=%p",
224 sink_class
= g_new0(struct bt_component_class_sink
, 1);
226 BT_LOGE_STR("Failed to allocate one sink component class.");
230 /* bt_component_class_init() logs errors */
231 ret
= bt_component_class_init(&sink_class
->parent
,
232 BT_COMPONENT_CLASS_TYPE_SINK
, name
);
235 * If bt_component_class_init() fails, the component
236 * class is put, therefore its memory is already
243 sink_class
->methods
.consume
= method
;
244 BT_LIB_LOGD("Created sink component class: %!+C", sink_class
);
247 return (void *) sink_class
;
250 int bt_component_class_source_set_init_method(
251 struct bt_component_class_source
*comp_cls
,
252 bt_component_class_source_init_method method
)
254 BT_ASSERT_PRE_NON_NULL(comp_cls
, "Component class");
255 BT_ASSERT_PRE_NON_NULL(method
, "Method");
256 BT_ASSERT_PRE_COMP_CLS_HOT(comp_cls
);
257 comp_cls
->methods
.init
= method
;
258 BT_LIB_LOGV("Set source component class's initialization method: "
263 int bt_component_class_filter_set_init_method(
264 struct bt_component_class_filter
*comp_cls
,
265 bt_component_class_filter_init_method method
)
267 BT_ASSERT_PRE_NON_NULL(comp_cls
, "Component class");
268 BT_ASSERT_PRE_NON_NULL(method
, "Method");
269 BT_ASSERT_PRE_COMP_CLS_HOT(comp_cls
);
270 comp_cls
->methods
.init
= method
;
271 BT_LIB_LOGV("Set filter component class's initialization method: "
276 int bt_component_class_sink_set_init_method(
277 struct bt_component_class_sink
*comp_cls
,
278 bt_component_class_sink_init_method method
)
280 BT_ASSERT_PRE_NON_NULL(comp_cls
, "Component class");
281 BT_ASSERT_PRE_NON_NULL(method
, "Method");
282 BT_ASSERT_PRE_COMP_CLS_HOT(comp_cls
);
283 comp_cls
->methods
.init
= method
;
284 BT_LIB_LOGV("Set sink component class's initialization method: "
289 int bt_component_class_source_set_finalize_method(
290 struct bt_component_class_source
*comp_cls
,
291 bt_component_class_source_finalize_method method
)
293 BT_ASSERT_PRE_NON_NULL(comp_cls
, "Component class");
294 BT_ASSERT_PRE_NON_NULL(method
, "Method");
295 BT_ASSERT_PRE_COMP_CLS_HOT(comp_cls
);
296 comp_cls
->methods
.finalize
= method
;
297 BT_LIB_LOGV("Set source component class's finalization method: "
302 int bt_component_class_filter_set_finalize_method(
303 struct bt_component_class_filter
*comp_cls
,
304 bt_component_class_filter_finalize_method method
)
306 BT_ASSERT_PRE_NON_NULL(comp_cls
, "Component class");
307 BT_ASSERT_PRE_NON_NULL(method
, "Method");
308 BT_ASSERT_PRE_COMP_CLS_HOT(comp_cls
);
309 comp_cls
->methods
.finalize
= method
;
310 BT_LIB_LOGV("Set filter component class's finalization method: "
315 int bt_component_class_sink_set_finalize_method(
316 struct bt_component_class_sink
*comp_cls
,
317 bt_component_class_sink_finalize_method method
)
319 BT_ASSERT_PRE_NON_NULL(comp_cls
, "Component class");
320 BT_ASSERT_PRE_NON_NULL(method
, "Method");
321 BT_ASSERT_PRE_COMP_CLS_HOT(comp_cls
);
322 comp_cls
->methods
.finalize
= method
;
323 BT_LIB_LOGV("Set sink component class's finalization method: "
328 int bt_component_class_source_set_query_method(
329 struct bt_component_class_source
*comp_cls
,
330 bt_component_class_source_query_method method
)
332 BT_ASSERT_PRE_NON_NULL(comp_cls
, "Component class");
333 BT_ASSERT_PRE_NON_NULL(method
, "Method");
334 BT_ASSERT_PRE_COMP_CLS_HOT(comp_cls
);
335 comp_cls
->methods
.query
= method
;
336 BT_LIB_LOGV("Set source component class's query method: "
341 int bt_component_class_filter_set_query_method(
342 struct bt_component_class_filter
*comp_cls
,
343 bt_component_class_filter_query_method method
)
345 BT_ASSERT_PRE_NON_NULL(comp_cls
, "Component class");
346 BT_ASSERT_PRE_NON_NULL(method
, "Method");
347 BT_ASSERT_PRE_COMP_CLS_HOT(comp_cls
);
348 comp_cls
->methods
.query
= method
;
349 BT_LIB_LOGV("Set filter component class's query method: "
354 int bt_component_class_sink_set_query_method(
355 struct bt_component_class_sink
*comp_cls
,
356 bt_component_class_sink_query_method method
)
358 BT_ASSERT_PRE_NON_NULL(comp_cls
, "Component class");
359 BT_ASSERT_PRE_NON_NULL(method
, "Method");
360 BT_ASSERT_PRE_COMP_CLS_HOT(comp_cls
);
361 comp_cls
->methods
.query
= method
;
362 BT_LIB_LOGV("Set sink component class's query method: "
367 int bt_component_class_filter_set_accept_input_port_connection_method(
368 struct bt_component_class_filter
*comp_cls
,
369 bt_component_class_filter_accept_input_port_connection_method method
)
371 BT_ASSERT_PRE_NON_NULL(comp_cls
, "Component class");
372 BT_ASSERT_PRE_NON_NULL(method
, "Method");
373 BT_ASSERT_PRE_COMP_CLS_HOT(comp_cls
);
374 comp_cls
->methods
.accept_input_port_connection
= method
;
375 BT_LIB_LOGV("Set filter component class's \"accept input port connection\" method"
380 int bt_component_class_sink_set_accept_input_port_connection_method(
381 struct bt_component_class_sink
*comp_cls
,
382 bt_component_class_sink_accept_input_port_connection_method method
)
384 BT_ASSERT_PRE_NON_NULL(comp_cls
, "Component class");
385 BT_ASSERT_PRE_NON_NULL(method
, "Method");
386 BT_ASSERT_PRE_COMP_CLS_HOT(comp_cls
);
387 comp_cls
->methods
.accept_input_port_connection
= method
;
388 BT_LIB_LOGV("Set sink component class's \"accept input port connection\" method"
393 int bt_component_class_source_set_accept_output_port_connection_method(
394 struct bt_component_class_source
*comp_cls
,
395 bt_component_class_source_accept_output_port_connection_method method
)
397 BT_ASSERT_PRE_NON_NULL(comp_cls
, "Component class");
398 BT_ASSERT_PRE_NON_NULL(method
, "Method");
399 BT_ASSERT_PRE_COMP_CLS_HOT(comp_cls
);
400 comp_cls
->methods
.accept_output_port_connection
= method
;
401 BT_LIB_LOGV("Set source component class's \"accept output port connection\" method"
406 int bt_component_class_filter_set_accept_output_port_connection_method(
407 struct bt_component_class_filter
*comp_cls
,
408 bt_component_class_filter_accept_output_port_connection_method method
)
410 BT_ASSERT_PRE_NON_NULL(comp_cls
, "Component class");
411 BT_ASSERT_PRE_NON_NULL(method
, "Method");
412 BT_ASSERT_PRE_COMP_CLS_HOT(comp_cls
);
413 comp_cls
->methods
.accept_output_port_connection
= method
;
414 BT_LIB_LOGV("Set filter component class's \"accept output port connection\" method"
419 int bt_component_class_filter_set_input_port_connected_method(
420 struct bt_component_class_filter
*comp_cls
,
421 bt_component_class_filter_input_port_connected_method method
)
423 BT_ASSERT_PRE_NON_NULL(comp_cls
, "Component class");
424 BT_ASSERT_PRE_NON_NULL(method
, "Method");
425 BT_ASSERT_PRE_COMP_CLS_HOT(comp_cls
);
426 comp_cls
->methods
.input_port_connected
= method
;
427 BT_LIB_LOGV("Set filter component class's \"input port connected\" method"
432 int bt_component_class_sink_set_input_port_connected_method(
433 struct bt_component_class_sink
*comp_cls
,
434 bt_component_class_sink_input_port_connected_method method
)
436 BT_ASSERT_PRE_NON_NULL(comp_cls
, "Component class");
437 BT_ASSERT_PRE_NON_NULL(method
, "Method");
438 BT_ASSERT_PRE_COMP_CLS_HOT(comp_cls
);
439 comp_cls
->methods
.input_port_connected
= method
;
440 BT_LIB_LOGV("Set sink component class's \"input port connected\" method"
445 int bt_component_class_source_set_output_port_connected_method(
446 struct bt_component_class_source
*comp_cls
,
447 bt_component_class_source_output_port_connected_method method
)
449 BT_ASSERT_PRE_NON_NULL(comp_cls
, "Component class");
450 BT_ASSERT_PRE_NON_NULL(method
, "Method");
451 BT_ASSERT_PRE_COMP_CLS_HOT(comp_cls
);
452 comp_cls
->methods
.output_port_connected
= method
;
453 BT_LIB_LOGV("Set source component class's \"output port connected\" method"
458 int bt_component_class_filter_set_output_port_connected_method(
459 struct bt_component_class_filter
*comp_cls
,
460 bt_component_class_filter_output_port_connected_method method
)
462 BT_ASSERT_PRE_NON_NULL(comp_cls
, "Component class");
463 BT_ASSERT_PRE_NON_NULL(method
, "Method");
464 BT_ASSERT_PRE_COMP_CLS_HOT(comp_cls
);
465 comp_cls
->methods
.output_port_connected
= method
;
466 BT_LIB_LOGV("Set filter component class's \"output port connected\" method"
471 int bt_component_class_filter_set_input_port_disconnected_method(
472 struct bt_component_class_filter
*comp_cls
,
473 bt_component_class_filter_input_port_disconnected_method method
)
475 BT_ASSERT_PRE_NON_NULL(comp_cls
, "Component class");
476 BT_ASSERT_PRE_NON_NULL(method
, "Method");
477 BT_ASSERT_PRE_COMP_CLS_HOT(comp_cls
);
478 comp_cls
->methods
.input_port_disconnected
= method
;
479 BT_LIB_LOGV("Set filter component class's \"input port disconnected\" method"
484 int bt_component_class_sink_set_input_port_disconnected_method(
485 struct bt_component_class_sink
*comp_cls
,
486 bt_component_class_sink_input_port_disconnected_method method
)
488 BT_ASSERT_PRE_NON_NULL(comp_cls
, "Component class");
489 BT_ASSERT_PRE_NON_NULL(method
, "Method");
490 BT_ASSERT_PRE_COMP_CLS_HOT(comp_cls
);
491 comp_cls
->methods
.input_port_disconnected
= method
;
492 BT_LIB_LOGV("Set sink component class's \"input port disconnected\" method"
497 int bt_component_class_source_set_output_port_disconnected_method(
498 struct bt_component_class_source
*comp_cls
,
499 bt_component_class_source_output_port_disconnected_method method
)
501 BT_ASSERT_PRE_NON_NULL(comp_cls
, "Component class");
502 BT_ASSERT_PRE_NON_NULL(method
, "Method");
503 BT_ASSERT_PRE_COMP_CLS_HOT(comp_cls
);
504 comp_cls
->methods
.output_port_disconnected
= method
;
505 BT_LIB_LOGV("Set source component class's \"output port disconnected\" method"
510 int bt_component_class_filter_set_output_port_disconnected_method(
511 struct bt_component_class_filter
*comp_cls
,
512 bt_component_class_filter_output_port_disconnected_method method
)
514 BT_ASSERT_PRE_NON_NULL(comp_cls
, "Component class");
515 BT_ASSERT_PRE_NON_NULL(method
, "Method");
516 BT_ASSERT_PRE_COMP_CLS_HOT(comp_cls
);
517 comp_cls
->methods
.output_port_disconnected
= method
;
518 BT_LIB_LOGV("Set filter component class's \"output port disconnected\" method"
523 int bt_component_class_source_set_notification_iterator_init_method(
524 struct bt_component_class_source
*comp_cls
,
525 bt_component_class_source_notification_iterator_init_method method
)
527 BT_ASSERT_PRE_NON_NULL(comp_cls
, "Component class");
528 BT_ASSERT_PRE_NON_NULL(method
, "Method");
529 BT_ASSERT_PRE_COMP_CLS_HOT(comp_cls
);
530 comp_cls
->methods
.notif_iter_init
= method
;
531 BT_LIB_LOGV("Set source component class's notification iterator initialization method"
536 int bt_component_class_filter_set_notification_iterator_init_method(
537 struct bt_component_class_filter
*comp_cls
,
538 bt_component_class_filter_notification_iterator_init_method method
)
540 BT_ASSERT_PRE_NON_NULL(comp_cls
, "Component class");
541 BT_ASSERT_PRE_NON_NULL(method
, "Method");
542 BT_ASSERT_PRE_COMP_CLS_HOT(comp_cls
);
543 comp_cls
->methods
.notif_iter_init
= method
;
544 BT_LIB_LOGV("Set filter component class's notification iterator initialization method"
549 int bt_component_class_source_set_notification_iterator_finalize_method(
550 struct bt_component_class_source
*comp_cls
,
551 bt_component_class_source_notification_iterator_finalize_method method
)
553 BT_ASSERT_PRE_NON_NULL(comp_cls
, "Component class");
554 BT_ASSERT_PRE_NON_NULL(method
, "Method");
555 BT_ASSERT_PRE_COMP_CLS_HOT(comp_cls
);
556 comp_cls
->methods
.notif_iter_finalize
= method
;
557 BT_LIB_LOGV("Set source component class's notification iterator finalization method"
562 int bt_component_class_filter_set_notification_iterator_finalize_method(
563 struct bt_component_class_filter
*comp_cls
,
564 bt_component_class_filter_notification_iterator_finalize_method method
)
566 BT_ASSERT_PRE_NON_NULL(comp_cls
, "Component class");
567 BT_ASSERT_PRE_NON_NULL(method
, "Method");
568 BT_ASSERT_PRE_COMP_CLS_HOT(comp_cls
);
569 comp_cls
->methods
.notif_iter_finalize
= method
;
570 BT_LIB_LOGV("Set filter component class's notification iterator finalization method"
575 int bt_component_class_set_description(
576 struct bt_component_class
*comp_cls
,
577 const char *description
)
579 BT_ASSERT_PRE_NON_NULL(comp_cls
, "Component class");
580 BT_ASSERT_PRE_NON_NULL(description
, "Description");
581 BT_ASSERT_PRE_COMP_CLS_HOT(comp_cls
);
582 g_string_assign(comp_cls
->description
, description
);
583 BT_LIB_LOGV("Set component class's description: "
584 "addr=%p, name=\"%s\", type=%s",
586 bt_component_class_get_name(comp_cls
),
587 bt_component_class_type_string(comp_cls
->type
));
591 int bt_component_class_set_help(
592 struct bt_component_class
*comp_cls
,
595 BT_ASSERT_PRE_NON_NULL(comp_cls
, "Component class");
596 BT_ASSERT_PRE_NON_NULL(help
, "Help");
597 BT_ASSERT_PRE_COMP_CLS_HOT(comp_cls
);
598 g_string_assign(comp_cls
->help
, help
);
599 BT_LIB_LOGV("Set component class's help text: %!+C", comp_cls
);
603 const char *bt_component_class_get_name(const struct bt_component_class
*comp_cls
)
605 BT_ASSERT_PRE_NON_NULL(comp_cls
, "Component class");
606 return comp_cls
->name
->str
;
609 enum bt_component_class_type
bt_component_class_get_type(
610 const struct bt_component_class
*comp_cls
)
612 BT_ASSERT_PRE_NON_NULL(comp_cls
, "Component class");
613 return comp_cls
->type
;
616 const char *bt_component_class_get_description(
617 const struct bt_component_class
*comp_cls
)
619 BT_ASSERT_PRE_NON_NULL(comp_cls
, "Component class");
620 return comp_cls
->description
&&
621 comp_cls
->description
->str
[0] != '\0' ?
622 comp_cls
->description
->str
: NULL
;
625 const char *bt_component_class_get_help(
626 const struct bt_component_class
*comp_cls
)
628 BT_ASSERT_PRE_NON_NULL(comp_cls
, "Component class");
629 return comp_cls
->help
&&
630 comp_cls
->help
->str
[0] != '\0' ? comp_cls
->help
->str
: NULL
;
634 void bt_component_class_add_destroy_listener(
635 struct bt_component_class
*comp_cls
,
636 bt_component_class_destroy_listener_func func
, void *data
)
638 struct bt_component_class_destroy_listener listener
;
642 listener
.func
= func
;
643 listener
.data
= data
;
644 g_array_append_val(comp_cls
->destroy_listeners
, listener
);
645 BT_LIB_LOGV("Added destroy listener to component class: "
646 "%![cc-]+C, listener-func-addr=%p", comp_cls
, func
);
650 void _bt_component_class_freeze(const struct bt_component_class
*comp_cls
)
653 BT_LIB_LOGD("Freezing component class: %!+C", comp_cls
);
654 ((struct bt_component_class
*) comp_cls
)->frozen
= true;