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/object.h>
35 #include <babeltrace/types.h>
36 #include <babeltrace/assert-internal.h>
40 void bt_component_class_destroy(struct bt_object
*obj
)
42 struct bt_component_class
*class;
46 class = container_of(obj
, struct bt_component_class
, base
);
48 BT_LOGD("Destroying component class: "
49 "addr=%p, name=\"%s\", type=%s",
50 class, bt_component_class_get_name(class),
51 bt_component_class_type_string(class->type
));
53 /* Call destroy listeners in reverse registration order */
54 for (i
= class->destroy_listeners
->len
- 1; i
>= 0; i
--) {
55 struct bt_component_class_destroy_listener
*listener
=
56 &g_array_index(class->destroy_listeners
,
57 struct bt_component_class_destroy_listener
,
60 BT_LOGD("Calling destroy listener: func-addr=%p, data-addr=%p",
61 listener
->func
, listener
->data
);
62 listener
->func(class, listener
->data
);
66 g_string_free(class->name
, TRUE
);
68 if (class->description
) {
69 g_string_free(class->description
, TRUE
);
72 g_string_free(class->help
, TRUE
);
74 if (class->destroy_listeners
) {
75 g_array_free(class->destroy_listeners
, TRUE
);
82 int bt_component_class_init(struct bt_component_class
*class,
83 enum bt_component_class_type type
, const char *name
)
87 bt_object_init_shared(&class->base
, bt_component_class_destroy
);
89 class->name
= g_string_new(name
);
91 BT_LOGE_STR("Failed to allocate a GString.");
95 class->description
= g_string_new(NULL
);
96 if (!class->description
) {
97 BT_LOGE_STR("Failed to allocate a GString.");
101 class->help
= g_string_new(NULL
);
103 BT_LOGE_STR("Failed to allocate a GString.");
107 class->destroy_listeners
= g_array_new(FALSE
, TRUE
,
108 sizeof(struct bt_component_class_destroy_listener
));
109 if (!class->destroy_listeners
) {
110 BT_LOGE_STR("Failed to allocate a GArray.");
117 BT_OBJECT_PUT_REF_AND_RESET(class);
124 struct bt_component_class
*bt_component_class_source_create(const char *name
,
125 bt_component_class_notification_iterator_next_method method
)
127 struct bt_component_class_source
*source_class
= NULL
;
131 BT_LOGW_STR("Invalid parameter: name is NULL.");
136 BT_LOGW_STR("Invalid parameter: method is NULL.");
140 BT_LOGD("Creating source component class: "
141 "name=\"%s\", notif-iter-next-method-addr=%p",
143 source_class
= g_new0(struct bt_component_class_source
, 1);
145 BT_LOGE_STR("Failed to allocate one source component class.");
149 /* bt_component_class_init() logs errors */
150 ret
= bt_component_class_init(&source_class
->parent
,
151 BT_COMPONENT_CLASS_TYPE_SOURCE
, name
);
154 * If bt_component_class_init() fails, the component
155 * class is put, therefore its memory is already
162 source_class
->methods
.iterator
.next
= method
;
163 BT_LOGD("Created source component class: "
164 "name=\"%s\", notif-iter-next-method-addr=%p, addr=%p",
165 name
, method
, &source_class
->parent
);
168 return &source_class
->parent
;
171 struct bt_component_class
*bt_component_class_filter_create(const char *name
,
172 bt_component_class_notification_iterator_next_method method
)
174 struct bt_component_class_filter
*filter_class
= NULL
;
178 BT_LOGW_STR("Invalid parameter: name is NULL.");
183 BT_LOGW_STR("Invalid parameter: method is NULL.");
187 BT_LOGD("Creating filter component class: "
188 "name=\"%s\", notif-iter-next-method-addr=%p",
190 filter_class
= g_new0(struct bt_component_class_filter
, 1);
192 BT_LOGE_STR("Failed to allocate one filter component class.");
196 /* bt_component_class_init() logs errors */
197 ret
= bt_component_class_init(&filter_class
->parent
,
198 BT_COMPONENT_CLASS_TYPE_FILTER
, name
);
201 * If bt_component_class_init() fails, the component
202 * class is put, therefore its memory is already
209 filter_class
->methods
.iterator
.next
= method
;
210 BT_LOGD("Created filter component class: "
211 "name=\"%s\", notif-iter-next-method-addr=%p, addr=%p",
212 name
, method
, &filter_class
->parent
);
215 return &filter_class
->parent
;
218 struct bt_component_class
*bt_component_class_sink_create(const char *name
,
219 bt_component_class_sink_consume_method method
)
221 struct bt_component_class_sink
*sink_class
= NULL
;
225 BT_LOGW_STR("Invalid parameter: name is NULL.");
230 BT_LOGW_STR("Invalid parameter: method is NULL.");
234 BT_LOGD("Creating sink component class: "
235 "name=\"%s\", consume-method-addr=%p",
237 sink_class
= g_new0(struct bt_component_class_sink
, 1);
239 BT_LOGE_STR("Failed to allocate one sink component class.");
243 /* bt_component_class_init() logs errors */
244 ret
= bt_component_class_init(&sink_class
->parent
,
245 BT_COMPONENT_CLASS_TYPE_SINK
, name
);
248 * If bt_component_class_init() fails, the component
249 * class is put, therefore its memory is already
256 sink_class
->methods
.consume
= method
;
257 BT_LOGD("Created sink component class: "
258 "name=\"%s\", consume-method-addr=%p, addr=%p",
259 name
, method
, &sink_class
->parent
);
262 return &sink_class
->parent
;
265 int bt_component_class_set_init_method(
266 struct bt_component_class
*component_class
,
267 bt_component_class_init_method method
)
271 if (!component_class
) {
272 BT_LOGW_STR("Invalid parameter: component class is NULL.");
278 BT_LOGW_STR("Invalid parameter: method is NULL.");
283 if (component_class
->frozen
) {
284 BT_LOGW("Invalid parameter: component class is frozen: "
285 "addr=%p, name=\"%s\", type=%s",
287 bt_component_class_get_name(component_class
),
288 bt_component_class_type_string(component_class
->type
));
293 component_class
->methods
.init
= method
;
294 BT_LOGV("Set component class's initialization method: "
295 "addr=%p, name=\"%s\", type=%s, method-addr=%p",
297 bt_component_class_get_name(component_class
),
298 bt_component_class_type_string(component_class
->type
),
305 int bt_component_class_set_query_method(
306 struct bt_component_class
*component_class
,
307 bt_component_class_query_method method
)
311 if (!component_class
) {
312 BT_LOGW_STR("Invalid parameter: component class is NULL.");
318 BT_LOGW_STR("Invalid parameter: method is NULL.");
323 if (component_class
->frozen
) {
324 BT_LOGW("Invalid parameter: component class is frozen: "
325 "addr=%p, name=\"%s\", type=%s",
327 bt_component_class_get_name(component_class
),
328 bt_component_class_type_string(component_class
->type
));
333 component_class
->methods
.query
= method
;
334 BT_LOGV("Set component class's query method: "
335 "addr=%p, name=\"%s\", type=%s, method-addr=%p",
337 bt_component_class_get_name(component_class
),
338 bt_component_class_type_string(component_class
->type
),
345 int bt_component_class_set_accept_port_connection_method(
346 struct bt_component_class
*component_class
,
347 bt_component_class_accept_port_connection_method method
)
351 if (!component_class
) {
352 BT_LOGW_STR("Invalid parameter: component class is NULL.");
358 BT_LOGW_STR("Invalid parameter: method is NULL.");
363 if (component_class
->frozen
) {
364 BT_LOGW("Invalid parameter: component class is frozen: "
365 "addr=%p, name=\"%s\", type=%s",
367 bt_component_class_get_name(component_class
),
368 bt_component_class_type_string(component_class
->type
));
373 component_class
->methods
.accept_port_connection
= method
;
374 BT_LOGV("Set component class's \"accept port connection\" method: "
375 "addr=%p, name=\"%s\", type=%s, method-addr=%p",
377 bt_component_class_get_name(component_class
),
378 bt_component_class_type_string(component_class
->type
),
385 int bt_component_class_set_port_connected_method(
386 struct bt_component_class
*component_class
,
387 bt_component_class_port_connected_method method
)
391 if (!component_class
) {
392 BT_LOGW_STR("Invalid parameter: component class is NULL.");
398 BT_LOGW_STR("Invalid parameter: method is NULL.");
403 if (component_class
->frozen
) {
404 BT_LOGW("Invalid parameter: component class is frozen: "
405 "addr=%p, name=\"%s\", type=%s",
407 bt_component_class_get_name(component_class
),
408 bt_component_class_type_string(component_class
->type
));
413 component_class
->methods
.port_connected
= method
;
414 BT_LOGV("Set component class's \"port connected\" method: "
415 "addr=%p, name=\"%s\", type=%s, method-addr=%p",
417 bt_component_class_get_name(component_class
),
418 bt_component_class_type_string(component_class
->type
),
425 int bt_component_class_set_port_disconnected_method(
426 struct bt_component_class
*component_class
,
427 bt_component_class_port_disconnected_method method
)
431 if (!component_class
) {
432 BT_LOGW_STR("Invalid parameter: component class is NULL.");
438 BT_LOGW_STR("Invalid parameter: method is NULL.");
443 if (component_class
->frozen
) {
444 BT_LOGW("Invalid parameter: component class is frozen: "
445 "addr=%p, name=\"%s\", type=%s",
447 bt_component_class_get_name(component_class
),
448 bt_component_class_type_string(component_class
->type
));
453 component_class
->methods
.port_disconnected
= method
;
454 BT_LOGV("Set component class's \"port disconnected\" method: "
455 "addr=%p, name=\"%s\", type=%s, method-addr=%p",
457 bt_component_class_get_name(component_class
),
458 bt_component_class_type_string(component_class
->type
),
465 int bt_component_class_set_finalize_method(
466 struct bt_component_class
*component_class
,
467 bt_component_class_finalize_method method
)
471 if (!component_class
) {
472 BT_LOGW_STR("Invalid parameter: component class is NULL.");
478 BT_LOGW_STR("Invalid parameter: method is NULL.");
483 if (component_class
->frozen
) {
484 BT_LOGW("Invalid parameter: component class is frozen: "
485 "addr=%p, name=\"%s\", type=%s",
487 bt_component_class_get_name(component_class
),
488 bt_component_class_type_string(component_class
->type
));
493 component_class
->methods
.finalize
= method
;
494 BT_LOGV("Set component class's finalization method: "
495 "addr=%p, name=\"%s\", type=%s, method-addr=%p",
497 bt_component_class_get_name(component_class
),
498 bt_component_class_type_string(component_class
->type
),
505 int bt_component_class_source_set_notification_iterator_init_method(
506 struct bt_component_class
*component_class
,
507 bt_component_class_notification_iterator_init_method method
)
509 struct bt_component_class_source
*source_class
;
512 if (!component_class
) {
513 BT_LOGW_STR("Invalid parameter: component class is NULL.");
519 BT_LOGW_STR("Invalid parameter: method is NULL.");
524 if (component_class
->type
!= BT_COMPONENT_CLASS_TYPE_SOURCE
) {
525 BT_LOGW("Invalid parameter: component class is not a source component class: "
526 "addr=%p, name=\"%s\", type=%s",
528 bt_component_class_get_name(component_class
),
529 bt_component_class_type_string(component_class
->type
));
534 if (component_class
->frozen
) {
535 BT_LOGW("Invalid parameter: component class is frozen: "
536 "addr=%p, name=\"%s\", type=%s",
538 bt_component_class_get_name(component_class
),
539 bt_component_class_type_string(component_class
->type
));
544 source_class
= container_of(component_class
,
545 struct bt_component_class_source
, parent
);
546 source_class
->methods
.iterator
.init
= method
;
547 BT_LOGV("Set filter component class's notification iterator initialization method: "
548 "addr=%p, name=\"%s\", method-addr=%p",
550 bt_component_class_get_name(component_class
),
557 int bt_component_class_source_set_notification_iterator_finalize_method(
558 struct bt_component_class
*component_class
,
559 bt_component_class_notification_iterator_finalize_method method
)
561 struct bt_component_class_source
*source_class
;
564 if (!component_class
) {
565 BT_LOGW_STR("Invalid parameter: component class is NULL.");
571 BT_LOGW_STR("Invalid parameter: method is NULL.");
576 if (component_class
->type
!= BT_COMPONENT_CLASS_TYPE_SOURCE
) {
577 BT_LOGW("Invalid parameter: component class is not a source component class: "
578 "addr=%p, name=\"%s\", type=%s",
580 bt_component_class_get_name(component_class
),
581 bt_component_class_type_string(component_class
->type
));
586 if (component_class
->frozen
) {
587 BT_LOGW("Invalid parameter: component class is frozen: "
588 "addr=%p, name=\"%s\", type=%s",
590 bt_component_class_get_name(component_class
),
591 bt_component_class_type_string(component_class
->type
));
596 source_class
= container_of(component_class
,
597 struct bt_component_class_source
, parent
);
598 source_class
->methods
.iterator
.finalize
=
600 BT_LOGV("Set filter component class's notification iterator finalization method: "
601 "addr=%p, name=\"%s\", method-addr=%p",
603 bt_component_class_get_name(component_class
),
610 int bt_component_class_filter_set_notification_iterator_init_method(
611 struct bt_component_class
*component_class
,
612 bt_component_class_notification_iterator_init_method method
)
614 struct bt_component_class_filter
*filter_class
;
617 if (!component_class
) {
618 BT_LOGW_STR("Invalid parameter: component class is NULL.");
624 BT_LOGW_STR("Invalid parameter: method is NULL.");
629 if (component_class
->type
!= BT_COMPONENT_CLASS_TYPE_FILTER
) {
630 BT_LOGW("Invalid parameter: component class is not a filter component class: "
631 "addr=%p, name=\"%s\", type=%s",
633 bt_component_class_get_name(component_class
),
634 bt_component_class_type_string(component_class
->type
));
639 if (component_class
->frozen
) {
640 BT_LOGW("Invalid parameter: component class is frozen: "
641 "addr=%p, name=\"%s\", type=%s",
643 bt_component_class_get_name(component_class
),
644 bt_component_class_type_string(component_class
->type
));
649 filter_class
= container_of(component_class
,
650 struct bt_component_class_filter
, parent
);
651 filter_class
->methods
.iterator
.init
= method
;
652 BT_LOGV("Set filter component class's notification iterator initialization method: "
653 "addr=%p, name=\"%s\", method-addr=%p",
655 bt_component_class_get_name(component_class
),
662 int bt_component_class_filter_set_notification_iterator_finalize_method(
663 struct bt_component_class
*component_class
,
664 bt_component_class_notification_iterator_finalize_method method
)
666 struct bt_component_class_filter
*filter_class
;
669 if (!component_class
) {
670 BT_LOGW_STR("Invalid parameter: component class is NULL.");
676 BT_LOGW_STR("Invalid parameter: method is NULL.");
681 if (component_class
->type
!= BT_COMPONENT_CLASS_TYPE_FILTER
) {
682 BT_LOGW("Invalid parameter: component class is not a filter component class: "
683 "addr=%p, name=\"%s\", type=%s",
685 bt_component_class_get_name(component_class
),
686 bt_component_class_type_string(component_class
->type
));
691 if (component_class
->frozen
) {
692 BT_LOGW("Invalid parameter: component class is frozen: "
693 "addr=%p, name=\"%s\", type=%s",
695 bt_component_class_get_name(component_class
),
696 bt_component_class_type_string(component_class
->type
));
701 filter_class
= container_of(component_class
,
702 struct bt_component_class_filter
, parent
);
703 filter_class
->methods
.iterator
.finalize
=
705 BT_LOGV("Set filter component class's notification iterator finalization method: "
706 "addr=%p, name=\"%s\", method-addr=%p",
708 bt_component_class_get_name(component_class
),
715 int bt_component_class_set_description(
716 struct bt_component_class
*component_class
,
717 const char *description
)
721 if (!component_class
) {
722 BT_LOGW_STR("Invalid parameter: component class is NULL.");
728 BT_LOGW_STR("Invalid parameter: description is NULL.");
733 if (component_class
->frozen
) {
734 BT_LOGW("Invalid parameter: component class is frozen: "
735 "addr=%p, name=\"%s\", type=%s",
737 bt_component_class_get_name(component_class
),
738 bt_component_class_type_string(component_class
->type
));
743 g_string_assign(component_class
->description
, description
);
744 BT_LOGV("Set component class's description: "
745 "addr=%p, name=\"%s\", type=%s",
747 bt_component_class_get_name(component_class
),
748 bt_component_class_type_string(component_class
->type
));
754 int bt_component_class_set_help(
755 struct bt_component_class
*component_class
,
760 if (!component_class
) {
761 BT_LOGW_STR("Invalid parameter: component class is NULL.");
767 BT_LOGW_STR("Invalid parameter: help is NULL.");
772 if (component_class
->frozen
) {
773 BT_LOGW("Invalid parameter: component class is frozen: "
774 "addr=%p, name=\"%s\", type=%s",
776 bt_component_class_get_name(component_class
),
777 bt_component_class_type_string(component_class
->type
));
782 g_string_assign(component_class
->help
, help
);
783 BT_LOGV("Set component class's help text: "
784 "addr=%p, name=\"%s\", type=%s",
786 bt_component_class_get_name(component_class
),
787 bt_component_class_type_string(component_class
->type
));
793 const char *bt_component_class_get_name(
794 struct bt_component_class
*component_class
)
796 return component_class
? component_class
->name
->str
: NULL
;
799 enum bt_component_class_type
bt_component_class_get_type(
800 struct bt_component_class
*component_class
)
802 return component_class
? component_class
->type
:
803 BT_COMPONENT_CLASS_TYPE_UNKNOWN
;
806 const char *bt_component_class_get_description(
807 struct bt_component_class
*component_class
)
809 return component_class
&& component_class
->description
&&
810 component_class
->description
->str
[0] != '\0' ?
811 component_class
->description
->str
: NULL
;
814 const char *bt_component_class_get_help(
815 struct bt_component_class
*component_class
)
817 return component_class
&& component_class
->help
&&
818 component_class
->help
->str
[0] != '\0' ?
819 component_class
->help
->str
: NULL
;
823 void bt_component_class_add_destroy_listener(struct bt_component_class
*class,
824 bt_component_class_destroy_listener_func func
, void *data
)
826 struct bt_component_class_destroy_listener listener
;
830 listener
.func
= func
;
831 listener
.data
= data
;
832 g_array_append_val(class->destroy_listeners
, listener
);
833 BT_LOGV("Component class has no registered query method: "
834 "comp-class-addr=%p, comp-class-name=\"%s\", comp-class-type=%s"
835 "func-addr=%p, data-addr=%p",
837 bt_component_class_get_name(class),
838 bt_component_class_type_string(class->type
),
842 int bt_component_class_freeze(
843 struct bt_component_class
*component_class
)
847 if (!component_class
) {
848 BT_LOGW_STR("Invalid parameter: component class is NULL.");
853 if (component_class
->frozen
) {
857 BT_LOGD("Freezing component class: "
858 "addr=%p, name=\"%s\", type=%s",
860 bt_component_class_get_name(component_class
),
861 bt_component_class_type_string(component_class
->type
));
862 component_class
->frozen
= BT_TRUE
;