4 * Babeltrace Plugin Component Class
6 * Copyright 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com>
8 * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
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:
17 * The above copyright notice and this permission notice shall be included in
18 * all copies or substantial portions of the Software.
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
29 #define BT_LOG_TAG "COMP-CLASS"
30 #include <babeltrace/lib-logging-internal.h>
32 #include <babeltrace/compiler-internal.h>
33 #include <babeltrace/graph/component-class-internal.h>
34 #include <babeltrace/ref.h>
35 #include <babeltrace/types.h>
39 void bt_component_class_destroy(struct bt_object
*obj
)
41 struct bt_component_class
*class;
45 class = container_of(obj
, struct bt_component_class
, base
);
47 BT_LOGD("Destroying component class: "
48 "addr=%p, name=\"%s\", type=%s",
49 class, bt_component_class_get_name(class),
50 bt_component_class_type_string(class->type
));
52 /* Call destroy listeners in reverse registration order */
53 for (i
= class->destroy_listeners
->len
- 1; i
>= 0; i
--) {
54 struct bt_component_class_destroy_listener
*listener
=
55 &g_array_index(class->destroy_listeners
,
56 struct bt_component_class_destroy_listener
,
59 BT_LOGD("Calling destroy listener: func-addr=%p, data-addr=%p",
60 listener
->func
, listener
->data
);
61 listener
->func(class, listener
->data
);
65 g_string_free(class->name
, TRUE
);
67 if (class->description
) {
68 g_string_free(class->description
, TRUE
);
71 g_string_free(class->help
, TRUE
);
73 if (class->destroy_listeners
) {
74 g_array_free(class->destroy_listeners
, TRUE
);
81 int bt_component_class_init(struct bt_component_class
*class,
82 enum bt_component_class_type type
, const char *name
)
86 bt_object_init(class, bt_component_class_destroy
);
88 class->name
= g_string_new(name
);
90 BT_LOGE_STR("Failed to allocate a GString.");
94 class->description
= g_string_new(NULL
);
95 if (!class->description
) {
96 BT_LOGE_STR("Failed to allocate a GString.");
100 class->help
= g_string_new(NULL
);
102 BT_LOGE_STR("Failed to allocate a GString.");
106 class->destroy_listeners
= g_array_new(FALSE
, TRUE
,
107 sizeof(struct bt_component_class_destroy_listener
));
108 if (!class->destroy_listeners
) {
109 BT_LOGE_STR("Failed to allocate a GArray.");
123 struct bt_component_class
*bt_component_class_source_create(const char *name
,
124 bt_component_class_notification_iterator_next_method method
)
126 struct bt_component_class_source
*source_class
= NULL
;
130 BT_LOGW_STR("Invalid parameter: name is NULL.");
135 BT_LOGW_STR("Invalid parameter: method is NULL.");
139 BT_LOGD("Creating source component class: "
140 "name=\"%s\", notif-iter-next-method-addr=%p",
142 source_class
= g_new0(struct bt_component_class_source
, 1);
144 BT_LOGE_STR("Failed to allocate one source component class.");
148 /* bt_component_class_init() logs errors */
149 ret
= bt_component_class_init(&source_class
->parent
,
150 BT_COMPONENT_CLASS_TYPE_SOURCE
, name
);
153 * If bt_component_class_init() fails, the component
154 * class is put, therefore its memory is already
161 source_class
->methods
.iterator
.next
= method
;
162 BT_LOGD("Created source component class: "
163 "name=\"%s\", notif-iter-next-method-addr=%p, addr=%p",
164 name
, method
, &source_class
->parent
);
167 return &source_class
->parent
;
170 struct bt_component_class
*bt_component_class_filter_create(const char *name
,
171 bt_component_class_notification_iterator_next_method method
)
173 struct bt_component_class_filter
*filter_class
= NULL
;
177 BT_LOGW_STR("Invalid parameter: name is NULL.");
182 BT_LOGW_STR("Invalid parameter: method is NULL.");
186 BT_LOGD("Creating filter component class: "
187 "name=\"%s\", notif-iter-next-method-addr=%p",
189 filter_class
= g_new0(struct bt_component_class_filter
, 1);
191 BT_LOGE_STR("Failed to allocate one filter component class.");
195 /* bt_component_class_init() logs errors */
196 ret
= bt_component_class_init(&filter_class
->parent
,
197 BT_COMPONENT_CLASS_TYPE_FILTER
, name
);
200 * If bt_component_class_init() fails, the component
201 * class is put, therefore its memory is already
208 filter_class
->methods
.iterator
.next
= method
;
209 BT_LOGD("Created filter component class: "
210 "name=\"%s\", notif-iter-next-method-addr=%p, addr=%p",
211 name
, method
, &filter_class
->parent
);
214 return &filter_class
->parent
;
217 struct bt_component_class
*bt_component_class_sink_create(const char *name
,
218 bt_component_class_sink_consume_method method
)
220 struct bt_component_class_sink
*sink_class
= NULL
;
224 BT_LOGW_STR("Invalid parameter: name is NULL.");
229 BT_LOGW_STR("Invalid parameter: method is NULL.");
233 BT_LOGD("Creating sink component class: "
234 "name=\"%s\", consume-method-addr=%p",
236 sink_class
= g_new0(struct bt_component_class_sink
, 1);
238 BT_LOGE_STR("Failed to allocate one sink component class.");
242 /* bt_component_class_init() logs errors */
243 ret
= bt_component_class_init(&sink_class
->parent
,
244 BT_COMPONENT_CLASS_TYPE_SINK
, name
);
247 * If bt_component_class_init() fails, the component
248 * class is put, therefore its memory is already
255 sink_class
->methods
.consume
= method
;
256 BT_LOGD("Created sink component class: "
257 "name=\"%s\", consume-method-addr=%p, addr=%p",
258 name
, method
, &sink_class
->parent
);
261 return &sink_class
->parent
;
264 int bt_component_class_set_init_method(
265 struct bt_component_class
*component_class
,
266 bt_component_class_init_method method
)
270 if (!component_class
) {
271 BT_LOGW_STR("Invalid parameter: component class is NULL.");
277 BT_LOGW_STR("Invalid parameter: method is NULL.");
282 if (component_class
->frozen
) {
283 BT_LOGW("Invalid parameter: component class is frozen: "
284 "addr=%p, name=\"%s\", type=%s",
286 bt_component_class_get_name(component_class
),
287 bt_component_class_type_string(component_class
->type
));
292 component_class
->methods
.init
= method
;
293 BT_LOGV("Set component class's initialization method: "
294 "addr=%p, name=\"%s\", type=%s, method-addr=%p",
296 bt_component_class_get_name(component_class
),
297 bt_component_class_type_string(component_class
->type
),
304 int bt_component_class_set_query_method(
305 struct bt_component_class
*component_class
,
306 bt_component_class_query_method method
)
310 if (!component_class
) {
311 BT_LOGW_STR("Invalid parameter: component class is NULL.");
317 BT_LOGW_STR("Invalid parameter: method is NULL.");
322 if (component_class
->frozen
) {
323 BT_LOGW("Invalid parameter: component class is frozen: "
324 "addr=%p, name=\"%s\", type=%s",
326 bt_component_class_get_name(component_class
),
327 bt_component_class_type_string(component_class
->type
));
332 component_class
->methods
.query
= method
;
333 BT_LOGV("Set component class's query method: "
334 "addr=%p, name=\"%s\", type=%s, method-addr=%p",
336 bt_component_class_get_name(component_class
),
337 bt_component_class_type_string(component_class
->type
),
344 int bt_component_class_set_accept_port_connection_method(
345 struct bt_component_class
*component_class
,
346 bt_component_class_accept_port_connection_method method
)
350 if (!component_class
) {
351 BT_LOGW_STR("Invalid parameter: component class is NULL.");
357 BT_LOGW_STR("Invalid parameter: method is NULL.");
362 if (component_class
->frozen
) {
363 BT_LOGW("Invalid parameter: component class is frozen: "
364 "addr=%p, name=\"%s\", type=%s",
366 bt_component_class_get_name(component_class
),
367 bt_component_class_type_string(component_class
->type
));
372 component_class
->methods
.accept_port_connection
= method
;
373 BT_LOGV("Set component class's \"accept port connection\" method: "
374 "addr=%p, name=\"%s\", type=%s, method-addr=%p",
376 bt_component_class_get_name(component_class
),
377 bt_component_class_type_string(component_class
->type
),
384 int bt_component_class_set_port_connected_method(
385 struct bt_component_class
*component_class
,
386 bt_component_class_port_connected_method method
)
390 if (!component_class
) {
391 BT_LOGW_STR("Invalid parameter: component class is NULL.");
397 BT_LOGW_STR("Invalid parameter: method is NULL.");
402 if (component_class
->frozen
) {
403 BT_LOGW("Invalid parameter: component class is frozen: "
404 "addr=%p, name=\"%s\", type=%s",
406 bt_component_class_get_name(component_class
),
407 bt_component_class_type_string(component_class
->type
));
412 component_class
->methods
.port_connected
= method
;
413 BT_LOGV("Set component class's \"port connected\" method: "
414 "addr=%p, name=\"%s\", type=%s, method-addr=%p",
416 bt_component_class_get_name(component_class
),
417 bt_component_class_type_string(component_class
->type
),
424 int bt_component_class_set_port_disconnected_method(
425 struct bt_component_class
*component_class
,
426 bt_component_class_port_disconnected_method method
)
430 if (!component_class
) {
431 BT_LOGW_STR("Invalid parameter: component class is NULL.");
437 BT_LOGW_STR("Invalid parameter: method is NULL.");
442 if (component_class
->frozen
) {
443 BT_LOGW("Invalid parameter: component class is frozen: "
444 "addr=%p, name=\"%s\", type=%s",
446 bt_component_class_get_name(component_class
),
447 bt_component_class_type_string(component_class
->type
));
452 component_class
->methods
.port_disconnected
= method
;
453 BT_LOGV("Set component class's \"port disconnected\" method: "
454 "addr=%p, name=\"%s\", type=%s, method-addr=%p",
456 bt_component_class_get_name(component_class
),
457 bt_component_class_type_string(component_class
->type
),
464 int bt_component_class_set_finalize_method(
465 struct bt_component_class
*component_class
,
466 bt_component_class_finalize_method method
)
470 if (!component_class
) {
471 BT_LOGW_STR("Invalid parameter: component class is NULL.");
477 BT_LOGW_STR("Invalid parameter: method is NULL.");
482 if (component_class
->frozen
) {
483 BT_LOGW("Invalid parameter: component class is frozen: "
484 "addr=%p, name=\"%s\", type=%s",
486 bt_component_class_get_name(component_class
),
487 bt_component_class_type_string(component_class
->type
));
492 component_class
->methods
.finalize
= method
;
493 BT_LOGV("Set component class's finalization method: "
494 "addr=%p, name=\"%s\", type=%s, method-addr=%p",
496 bt_component_class_get_name(component_class
),
497 bt_component_class_type_string(component_class
->type
),
504 int bt_component_class_source_set_notification_iterator_init_method(
505 struct bt_component_class
*component_class
,
506 bt_component_class_notification_iterator_init_method method
)
508 struct bt_component_class_source
*source_class
;
511 if (!component_class
) {
512 BT_LOGW_STR("Invalid parameter: component class is NULL.");
518 BT_LOGW_STR("Invalid parameter: method is NULL.");
523 if (component_class
->type
!= BT_COMPONENT_CLASS_TYPE_SOURCE
) {
524 BT_LOGW("Invalid parameter: component class is not a source component class: "
525 "addr=%p, name=\"%s\", type=%s",
527 bt_component_class_get_name(component_class
),
528 bt_component_class_type_string(component_class
->type
));
533 if (component_class
->frozen
) {
534 BT_LOGW("Invalid parameter: component class is frozen: "
535 "addr=%p, name=\"%s\", type=%s",
537 bt_component_class_get_name(component_class
),
538 bt_component_class_type_string(component_class
->type
));
543 source_class
= container_of(component_class
,
544 struct bt_component_class_source
, parent
);
545 source_class
->methods
.iterator
.init
= method
;
546 BT_LOGV("Set filter component class's notification iterator initialization method: "
547 "addr=%p, name=\"%s\", method-addr=%p",
549 bt_component_class_get_name(component_class
),
556 int bt_component_class_source_set_notification_iterator_finalize_method(
557 struct bt_component_class
*component_class
,
558 bt_component_class_notification_iterator_finalize_method method
)
560 struct bt_component_class_source
*source_class
;
563 if (!component_class
) {
564 BT_LOGW_STR("Invalid parameter: component class is NULL.");
570 BT_LOGW_STR("Invalid parameter: method is NULL.");
575 if (component_class
->type
!= BT_COMPONENT_CLASS_TYPE_SOURCE
) {
576 BT_LOGW("Invalid parameter: component class is not a source component class: "
577 "addr=%p, name=\"%s\", type=%s",
579 bt_component_class_get_name(component_class
),
580 bt_component_class_type_string(component_class
->type
));
585 if (component_class
->frozen
) {
586 BT_LOGW("Invalid parameter: component class is frozen: "
587 "addr=%p, name=\"%s\", type=%s",
589 bt_component_class_get_name(component_class
),
590 bt_component_class_type_string(component_class
->type
));
595 source_class
= container_of(component_class
,
596 struct bt_component_class_source
, parent
);
597 source_class
->methods
.iterator
.finalize
=
599 BT_LOGV("Set filter component class's notification iterator finalization method: "
600 "addr=%p, name=\"%s\", method-addr=%p",
602 bt_component_class_get_name(component_class
),
609 int bt_component_class_filter_set_notification_iterator_init_method(
610 struct bt_component_class
*component_class
,
611 bt_component_class_notification_iterator_init_method method
)
613 struct bt_component_class_filter
*filter_class
;
616 if (!component_class
) {
617 BT_LOGW_STR("Invalid parameter: component class is NULL.");
623 BT_LOGW_STR("Invalid parameter: method is NULL.");
628 if (component_class
->type
!= BT_COMPONENT_CLASS_TYPE_FILTER
) {
629 BT_LOGW("Invalid parameter: component class is not a filter component class: "
630 "addr=%p, name=\"%s\", type=%s",
632 bt_component_class_get_name(component_class
),
633 bt_component_class_type_string(component_class
->type
));
638 if (component_class
->frozen
) {
639 BT_LOGW("Invalid parameter: component class is frozen: "
640 "addr=%p, name=\"%s\", type=%s",
642 bt_component_class_get_name(component_class
),
643 bt_component_class_type_string(component_class
->type
));
648 filter_class
= container_of(component_class
,
649 struct bt_component_class_filter
, parent
);
650 filter_class
->methods
.iterator
.init
= method
;
651 BT_LOGV("Set filter component class's notification iterator initialization method: "
652 "addr=%p, name=\"%s\", method-addr=%p",
654 bt_component_class_get_name(component_class
),
661 int bt_component_class_filter_set_notification_iterator_finalize_method(
662 struct bt_component_class
*component_class
,
663 bt_component_class_notification_iterator_finalize_method method
)
665 struct bt_component_class_filter
*filter_class
;
668 if (!component_class
) {
669 BT_LOGW_STR("Invalid parameter: component class is NULL.");
675 BT_LOGW_STR("Invalid parameter: method is NULL.");
680 if (component_class
->type
!= BT_COMPONENT_CLASS_TYPE_FILTER
) {
681 BT_LOGW("Invalid parameter: component class is not a filter component class: "
682 "addr=%p, name=\"%s\", type=%s",
684 bt_component_class_get_name(component_class
),
685 bt_component_class_type_string(component_class
->type
));
690 if (component_class
->frozen
) {
691 BT_LOGW("Invalid parameter: component class is frozen: "
692 "addr=%p, name=\"%s\", type=%s",
694 bt_component_class_get_name(component_class
),
695 bt_component_class_type_string(component_class
->type
));
700 filter_class
= container_of(component_class
,
701 struct bt_component_class_filter
, parent
);
702 filter_class
->methods
.iterator
.finalize
=
704 BT_LOGV("Set filter component class's notification iterator finalization method: "
705 "addr=%p, name=\"%s\", method-addr=%p",
707 bt_component_class_get_name(component_class
),
714 int bt_component_class_set_description(
715 struct bt_component_class
*component_class
,
716 const char *description
)
720 if (!component_class
) {
721 BT_LOGW_STR("Invalid parameter: component class is NULL.");
727 BT_LOGW_STR("Invalid parameter: description is NULL.");
732 if (component_class
->frozen
) {
733 BT_LOGW("Invalid parameter: component class is frozen: "
734 "addr=%p, name=\"%s\", type=%s",
736 bt_component_class_get_name(component_class
),
737 bt_component_class_type_string(component_class
->type
));
742 g_string_assign(component_class
->description
, description
);
743 BT_LOGV("Set component class's description: "
744 "addr=%p, name=\"%s\", type=%s",
746 bt_component_class_get_name(component_class
),
747 bt_component_class_type_string(component_class
->type
));
753 int bt_component_class_set_help(
754 struct bt_component_class
*component_class
,
759 if (!component_class
) {
760 BT_LOGW_STR("Invalid parameter: component class is NULL.");
766 BT_LOGW_STR("Invalid parameter: help is NULL.");
771 if (component_class
->frozen
) {
772 BT_LOGW("Invalid parameter: component class is frozen: "
773 "addr=%p, name=\"%s\", type=%s",
775 bt_component_class_get_name(component_class
),
776 bt_component_class_type_string(component_class
->type
));
781 g_string_assign(component_class
->help
, help
);
782 BT_LOGV("Set component class's help text: "
783 "addr=%p, name=\"%s\", type=%s",
785 bt_component_class_get_name(component_class
),
786 bt_component_class_type_string(component_class
->type
));
792 const char *bt_component_class_get_name(
793 struct bt_component_class
*component_class
)
795 return component_class
? component_class
->name
->str
: NULL
;
798 enum bt_component_class_type
bt_component_class_get_type(
799 struct bt_component_class
*component_class
)
801 return component_class
? component_class
->type
:
802 BT_COMPONENT_CLASS_TYPE_UNKNOWN
;
805 const char *bt_component_class_get_description(
806 struct bt_component_class
*component_class
)
808 return component_class
&& component_class
->description
&&
809 component_class
->description
->str
[0] != '\0' ?
810 component_class
->description
->str
: NULL
;
813 const char *bt_component_class_get_help(
814 struct bt_component_class
*component_class
)
816 return component_class
&& component_class
->help
&&
817 component_class
->help
->str
[0] != '\0' ?
818 component_class
->help
->str
: NULL
;
822 void bt_component_class_add_destroy_listener(struct bt_component_class
*class,
823 bt_component_class_destroy_listener_func func
, void *data
)
825 struct bt_component_class_destroy_listener listener
;
829 listener
.func
= func
;
830 listener
.data
= data
;
831 g_array_append_val(class->destroy_listeners
, listener
);
832 BT_LOGV("Component class has no registered query method: "
833 "comp-class-addr=%p, comp-class-name=\"%s\", comp-class-type=%s"
834 "func-addr=%p, data-addr=%p",
836 bt_component_class_get_name(class),
837 bt_component_class_type_string(class->type
),
841 int bt_component_class_freeze(
842 struct bt_component_class
*component_class
)
846 if (!component_class
) {
847 BT_LOGW_STR("Invalid parameter: component class is NULL.");
852 if (component_class
->frozen
) {
856 BT_LOGD("Freezing component class: "
857 "addr=%p, name=\"%s\", type=%s",
859 bt_component_class_get_name(component_class
),
860 bt_component_class_type_string(component_class
->type
));
861 component_class
->frozen
= BT_TRUE
;