2 * Copyright 2017-2018 Philippe Proulx <pproulx@efficios.com>
3 * Copyright 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com>
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 #define BT_LOG_TAG "COMP-CLASS"
25 #include <babeltrace/lib-logging-internal.h>
27 #include <babeltrace/assert-internal.h>
28 #include <babeltrace/assert-pre-internal.h>
29 #include <babeltrace/compiler-internal.h>
30 #include <babeltrace/graph/component-class.h>
31 #include <babeltrace/graph/component-class-const.h>
32 #include <babeltrace/graph/component-class-source.h>
33 #include <babeltrace/graph/component-class-source-const.h>
34 #include <babeltrace/graph/component-class-filter.h>
35 #include <babeltrace/graph/component-class-filter-const.h>
36 #include <babeltrace/graph/component-class-sink.h>
37 #include <babeltrace/graph/component-class-sink-const.h>
38 #include <babeltrace/graph/component-class-internal.h>
39 #include <babeltrace/types.h>
42 #define BT_ASSERT_PRE_COMP_CLS_HOT(_cc) \
43 BT_ASSERT_PRE_HOT(((const struct bt_component_class *) (_cc)), \
44 "Component class", ": %!+C", (_cc))
47 void destroy_component_class(struct bt_object
*obj
)
49 struct bt_component_class
*class;
53 class = container_of(obj
, struct bt_component_class
, base
);
55 BT_LIB_LOGD("Destroying component class: %!+C", class);
57 /* Call destroy listeners in reverse registration order */
58 for (i
= class->destroy_listeners
->len
- 1; i
>= 0; i
--) {
59 struct bt_component_class_destroy_listener
*listener
=
60 &g_array_index(class->destroy_listeners
,
61 struct bt_component_class_destroy_listener
,
64 BT_LOGD("Calling destroy listener: func-addr=%p, data-addr=%p",
65 listener
->func
, listener
->data
);
66 listener
->func(class, listener
->data
);
70 g_string_free(class->name
, TRUE
);
74 if (class->description
) {
75 g_string_free(class->description
, TRUE
);
76 class->description
= NULL
;
80 g_string_free(class->help
, TRUE
);
84 if (class->destroy_listeners
) {
85 g_array_free(class->destroy_listeners
, TRUE
);
86 class->destroy_listeners
= NULL
;
93 int bt_component_class_init(struct bt_component_class
*class,
94 enum bt_component_class_type type
, const char *name
)
98 bt_object_init_shared(&class->base
, destroy_component_class
);
100 class->name
= g_string_new(name
);
102 BT_LOGE_STR("Failed to allocate a GString.");
106 class->description
= g_string_new(NULL
);
107 if (!class->description
) {
108 BT_LOGE_STR("Failed to allocate a GString.");
112 class->help
= g_string_new(NULL
);
114 BT_LOGE_STR("Failed to allocate a GString.");
118 class->destroy_listeners
= g_array_new(FALSE
, TRUE
,
119 sizeof(struct bt_component_class_destroy_listener
));
120 if (!class->destroy_listeners
) {
121 BT_LOGE_STR("Failed to allocate a GArray.");
128 BT_OBJECT_PUT_REF_AND_RESET(class);
135 struct bt_component_class_source
*bt_component_class_source_create(
137 bt_component_class_source_message_iterator_next_method method
)
139 struct bt_component_class_source
*source_class
= NULL
;
142 BT_ASSERT_PRE_NON_NULL(name
, "Name");
143 BT_ASSERT_PRE_NON_NULL(method
, "Message iterator next method");
144 BT_LOGD("Creating source component class: "
145 "name=\"%s\", msg-iter-next-method-addr=%p",
147 source_class
= g_new0(struct bt_component_class_source
, 1);
149 BT_LOGE_STR("Failed to allocate one source component class.");
153 /* bt_component_class_init() logs errors */
154 ret
= bt_component_class_init(&source_class
->parent
,
155 BT_COMPONENT_CLASS_TYPE_SOURCE
, name
);
158 * If bt_component_class_init() fails, the component
159 * class is put, therefore its memory is already
166 source_class
->methods
.msg_iter_next
= method
;
167 BT_LIB_LOGD("Created source component class: %!+C", source_class
);
170 return (void *) source_class
;
173 struct bt_component_class_filter
*bt_component_class_filter_create(
175 bt_component_class_filter_message_iterator_next_method method
)
177 struct bt_component_class_filter
*filter_class
= NULL
;
180 BT_ASSERT_PRE_NON_NULL(name
, "Name");
181 BT_ASSERT_PRE_NON_NULL(method
, "Message iterator next method");
182 BT_LOGD("Creating filter component class: "
183 "name=\"%s\", msg-iter-next-method-addr=%p",
185 filter_class
= g_new0(struct bt_component_class_filter
, 1);
187 BT_LOGE_STR("Failed to allocate one filter component class.");
191 /* bt_component_class_init() logs errors */
192 ret
= bt_component_class_init(&filter_class
->parent
,
193 BT_COMPONENT_CLASS_TYPE_FILTER
, name
);
196 * If bt_component_class_init() fails, the component
197 * class is put, therefore its memory is already
204 filter_class
->methods
.msg_iter_next
= method
;
205 BT_LIB_LOGD("Created filter component class: %!+C", filter_class
);
208 return (void *) filter_class
;
211 struct bt_component_class_sink
*bt_component_class_sink_create(
212 const char *name
, bt_component_class_sink_consume_method method
)
214 struct bt_component_class_sink
*sink_class
= NULL
;
217 BT_ASSERT_PRE_NON_NULL(name
, "Name");
218 BT_ASSERT_PRE_NON_NULL(method
, "Consume next method");
219 BT_LOGD("Creating sink component class: "
220 "name=\"%s\", consume-method-addr=%p",
222 sink_class
= g_new0(struct bt_component_class_sink
, 1);
224 BT_LOGE_STR("Failed to allocate one sink component class.");
228 /* bt_component_class_init() logs errors */
229 ret
= bt_component_class_init(&sink_class
->parent
,
230 BT_COMPONENT_CLASS_TYPE_SINK
, name
);
233 * If bt_component_class_init() fails, the component
234 * class is put, therefore its memory is already
241 sink_class
->methods
.consume
= method
;
242 BT_LIB_LOGD("Created sink component class: %!+C", sink_class
);
245 return (void *) sink_class
;
248 int bt_component_class_source_set_init_method(
249 struct bt_component_class_source
*comp_cls
,
250 bt_component_class_source_init_method method
)
252 BT_ASSERT_PRE_NON_NULL(comp_cls
, "Component class");
253 BT_ASSERT_PRE_NON_NULL(method
, "Method");
254 BT_ASSERT_PRE_COMP_CLS_HOT(comp_cls
);
255 comp_cls
->methods
.init
= method
;
256 BT_LIB_LOGV("Set source component class's initialization method: "
258 return BT_COMPONENT_CLASS_STATUS_OK
;
261 int bt_component_class_filter_set_init_method(
262 struct bt_component_class_filter
*comp_cls
,
263 bt_component_class_filter_init_method method
)
265 BT_ASSERT_PRE_NON_NULL(comp_cls
, "Component class");
266 BT_ASSERT_PRE_NON_NULL(method
, "Method");
267 BT_ASSERT_PRE_COMP_CLS_HOT(comp_cls
);
268 comp_cls
->methods
.init
= method
;
269 BT_LIB_LOGV("Set filter component class's initialization method: "
271 return BT_COMPONENT_CLASS_STATUS_OK
;
274 int bt_component_class_sink_set_init_method(
275 struct bt_component_class_sink
*comp_cls
,
276 bt_component_class_sink_init_method method
)
278 BT_ASSERT_PRE_NON_NULL(comp_cls
, "Component class");
279 BT_ASSERT_PRE_NON_NULL(method
, "Method");
280 BT_ASSERT_PRE_COMP_CLS_HOT(comp_cls
);
281 comp_cls
->methods
.init
= method
;
282 BT_LIB_LOGV("Set sink component class's initialization method: "
284 return BT_COMPONENT_CLASS_STATUS_OK
;
287 int bt_component_class_source_set_finalize_method(
288 struct bt_component_class_source
*comp_cls
,
289 bt_component_class_source_finalize_method method
)
291 BT_ASSERT_PRE_NON_NULL(comp_cls
, "Component class");
292 BT_ASSERT_PRE_NON_NULL(method
, "Method");
293 BT_ASSERT_PRE_COMP_CLS_HOT(comp_cls
);
294 comp_cls
->methods
.finalize
= method
;
295 BT_LIB_LOGV("Set source component class's finalization method: "
297 return BT_COMPONENT_CLASS_STATUS_OK
;
300 int bt_component_class_filter_set_finalize_method(
301 struct bt_component_class_filter
*comp_cls
,
302 bt_component_class_filter_finalize_method method
)
304 BT_ASSERT_PRE_NON_NULL(comp_cls
, "Component class");
305 BT_ASSERT_PRE_NON_NULL(method
, "Method");
306 BT_ASSERT_PRE_COMP_CLS_HOT(comp_cls
);
307 comp_cls
->methods
.finalize
= method
;
308 BT_LIB_LOGV("Set filter component class's finalization method: "
310 return BT_COMPONENT_CLASS_STATUS_OK
;
313 int bt_component_class_sink_set_finalize_method(
314 struct bt_component_class_sink
*comp_cls
,
315 bt_component_class_sink_finalize_method method
)
317 BT_ASSERT_PRE_NON_NULL(comp_cls
, "Component class");
318 BT_ASSERT_PRE_NON_NULL(method
, "Method");
319 BT_ASSERT_PRE_COMP_CLS_HOT(comp_cls
);
320 comp_cls
->methods
.finalize
= method
;
321 BT_LIB_LOGV("Set sink component class's finalization method: "
323 return BT_COMPONENT_CLASS_STATUS_OK
;
326 int bt_component_class_source_set_query_method(
327 struct bt_component_class_source
*comp_cls
,
328 bt_component_class_source_query_method method
)
330 BT_ASSERT_PRE_NON_NULL(comp_cls
, "Component class");
331 BT_ASSERT_PRE_NON_NULL(method
, "Method");
332 BT_ASSERT_PRE_COMP_CLS_HOT(comp_cls
);
333 comp_cls
->methods
.query
= method
;
334 BT_LIB_LOGV("Set source component class's query method: "
336 return BT_COMPONENT_CLASS_STATUS_OK
;
339 int bt_component_class_filter_set_query_method(
340 struct bt_component_class_filter
*comp_cls
,
341 bt_component_class_filter_query_method method
)
343 BT_ASSERT_PRE_NON_NULL(comp_cls
, "Component class");
344 BT_ASSERT_PRE_NON_NULL(method
, "Method");
345 BT_ASSERT_PRE_COMP_CLS_HOT(comp_cls
);
346 comp_cls
->methods
.query
= method
;
347 BT_LIB_LOGV("Set filter component class's query method: "
349 return BT_COMPONENT_CLASS_STATUS_OK
;
352 int bt_component_class_sink_set_query_method(
353 struct bt_component_class_sink
*comp_cls
,
354 bt_component_class_sink_query_method method
)
356 BT_ASSERT_PRE_NON_NULL(comp_cls
, "Component class");
357 BT_ASSERT_PRE_NON_NULL(method
, "Method");
358 BT_ASSERT_PRE_COMP_CLS_HOT(comp_cls
);
359 comp_cls
->methods
.query
= method
;
360 BT_LIB_LOGV("Set sink component class's query method: "
362 return BT_COMPONENT_CLASS_STATUS_OK
;
365 int bt_component_class_filter_set_accept_input_port_connection_method(
366 struct bt_component_class_filter
*comp_cls
,
367 bt_component_class_filter_accept_input_port_connection_method method
)
369 BT_ASSERT_PRE_NON_NULL(comp_cls
, "Component class");
370 BT_ASSERT_PRE_NON_NULL(method
, "Method");
371 BT_ASSERT_PRE_COMP_CLS_HOT(comp_cls
);
372 comp_cls
->methods
.accept_input_port_connection
= method
;
373 BT_LIB_LOGV("Set filter component class's \"accept input port connection\" method"
375 return BT_COMPONENT_CLASS_STATUS_OK
;
378 int bt_component_class_sink_set_accept_input_port_connection_method(
379 struct bt_component_class_sink
*comp_cls
,
380 bt_component_class_sink_accept_input_port_connection_method method
)
382 BT_ASSERT_PRE_NON_NULL(comp_cls
, "Component class");
383 BT_ASSERT_PRE_NON_NULL(method
, "Method");
384 BT_ASSERT_PRE_COMP_CLS_HOT(comp_cls
);
385 comp_cls
->methods
.accept_input_port_connection
= method
;
386 BT_LIB_LOGV("Set sink component class's \"accept input port connection\" method"
388 return BT_COMPONENT_CLASS_STATUS_OK
;
391 int bt_component_class_source_set_accept_output_port_connection_method(
392 struct bt_component_class_source
*comp_cls
,
393 bt_component_class_source_accept_output_port_connection_method method
)
395 BT_ASSERT_PRE_NON_NULL(comp_cls
, "Component class");
396 BT_ASSERT_PRE_NON_NULL(method
, "Method");
397 BT_ASSERT_PRE_COMP_CLS_HOT(comp_cls
);
398 comp_cls
->methods
.accept_output_port_connection
= method
;
399 BT_LIB_LOGV("Set source component class's \"accept output port connection\" method"
401 return BT_COMPONENT_CLASS_STATUS_OK
;
404 int bt_component_class_filter_set_accept_output_port_connection_method(
405 struct bt_component_class_filter
*comp_cls
,
406 bt_component_class_filter_accept_output_port_connection_method method
)
408 BT_ASSERT_PRE_NON_NULL(comp_cls
, "Component class");
409 BT_ASSERT_PRE_NON_NULL(method
, "Method");
410 BT_ASSERT_PRE_COMP_CLS_HOT(comp_cls
);
411 comp_cls
->methods
.accept_output_port_connection
= method
;
412 BT_LIB_LOGV("Set filter component class's \"accept output port connection\" method"
414 return BT_COMPONENT_CLASS_STATUS_OK
;
417 int bt_component_class_filter_set_input_port_connected_method(
418 struct bt_component_class_filter
*comp_cls
,
419 bt_component_class_filter_input_port_connected_method method
)
421 BT_ASSERT_PRE_NON_NULL(comp_cls
, "Component class");
422 BT_ASSERT_PRE_NON_NULL(method
, "Method");
423 BT_ASSERT_PRE_COMP_CLS_HOT(comp_cls
);
424 comp_cls
->methods
.input_port_connected
= method
;
425 BT_LIB_LOGV("Set filter component class's \"input port connected\" method"
427 return BT_COMPONENT_CLASS_STATUS_OK
;
430 int bt_component_class_sink_set_input_port_connected_method(
431 struct bt_component_class_sink
*comp_cls
,
432 bt_component_class_sink_input_port_connected_method method
)
434 BT_ASSERT_PRE_NON_NULL(comp_cls
, "Component class");
435 BT_ASSERT_PRE_NON_NULL(method
, "Method");
436 BT_ASSERT_PRE_COMP_CLS_HOT(comp_cls
);
437 comp_cls
->methods
.input_port_connected
= method
;
438 BT_LIB_LOGV("Set sink component class's \"input port connected\" method"
440 return BT_COMPONENT_CLASS_STATUS_OK
;
443 int bt_component_class_source_set_output_port_connected_method(
444 struct bt_component_class_source
*comp_cls
,
445 bt_component_class_source_output_port_connected_method method
)
447 BT_ASSERT_PRE_NON_NULL(comp_cls
, "Component class");
448 BT_ASSERT_PRE_NON_NULL(method
, "Method");
449 BT_ASSERT_PRE_COMP_CLS_HOT(comp_cls
);
450 comp_cls
->methods
.output_port_connected
= method
;
451 BT_LIB_LOGV("Set source component class's \"output port connected\" method"
453 return BT_COMPONENT_CLASS_STATUS_OK
;
456 int bt_component_class_filter_set_output_port_connected_method(
457 struct bt_component_class_filter
*comp_cls
,
458 bt_component_class_filter_output_port_connected_method method
)
460 BT_ASSERT_PRE_NON_NULL(comp_cls
, "Component class");
461 BT_ASSERT_PRE_NON_NULL(method
, "Method");
462 BT_ASSERT_PRE_COMP_CLS_HOT(comp_cls
);
463 comp_cls
->methods
.output_port_connected
= method
;
464 BT_LIB_LOGV("Set filter component class's \"output port connected\" method"
466 return BT_COMPONENT_CLASS_STATUS_OK
;
469 int bt_component_class_source_set_message_iterator_init_method(
470 struct bt_component_class_source
*comp_cls
,
471 bt_component_class_source_message_iterator_init_method method
)
473 BT_ASSERT_PRE_NON_NULL(comp_cls
, "Component class");
474 BT_ASSERT_PRE_NON_NULL(method
, "Method");
475 BT_ASSERT_PRE_COMP_CLS_HOT(comp_cls
);
476 comp_cls
->methods
.msg_iter_init
= method
;
477 BT_LIB_LOGV("Set source component class's message iterator initialization method"
479 return BT_COMPONENT_CLASS_STATUS_OK
;
482 int bt_component_class_filter_set_message_iterator_init_method(
483 struct bt_component_class_filter
*comp_cls
,
484 bt_component_class_filter_message_iterator_init_method method
)
486 BT_ASSERT_PRE_NON_NULL(comp_cls
, "Component class");
487 BT_ASSERT_PRE_NON_NULL(method
, "Method");
488 BT_ASSERT_PRE_COMP_CLS_HOT(comp_cls
);
489 comp_cls
->methods
.msg_iter_init
= method
;
490 BT_LIB_LOGV("Set filter component class's message iterator initialization method"
492 return BT_COMPONENT_CLASS_STATUS_OK
;
495 int bt_component_class_source_set_message_iterator_finalize_method(
496 struct bt_component_class_source
*comp_cls
,
497 bt_component_class_source_message_iterator_finalize_method method
)
499 BT_ASSERT_PRE_NON_NULL(comp_cls
, "Component class");
500 BT_ASSERT_PRE_NON_NULL(method
, "Method");
501 BT_ASSERT_PRE_COMP_CLS_HOT(comp_cls
);
502 comp_cls
->methods
.msg_iter_finalize
= method
;
503 BT_LIB_LOGV("Set source component class's message iterator finalization method"
505 return BT_COMPONENT_CLASS_STATUS_OK
;
508 int bt_component_class_filter_set_message_iterator_finalize_method(
509 struct bt_component_class_filter
*comp_cls
,
510 bt_component_class_filter_message_iterator_finalize_method method
)
512 BT_ASSERT_PRE_NON_NULL(comp_cls
, "Component class");
513 BT_ASSERT_PRE_NON_NULL(method
, "Method");
514 BT_ASSERT_PRE_COMP_CLS_HOT(comp_cls
);
515 comp_cls
->methods
.msg_iter_finalize
= method
;
516 BT_LIB_LOGV("Set filter component class's message iterator finalization method"
518 return BT_COMPONENT_CLASS_STATUS_OK
;
521 bt_component_class_status
bt_component_class_set_description(
522 struct bt_component_class
*comp_cls
,
523 const char *description
)
525 BT_ASSERT_PRE_NON_NULL(comp_cls
, "Component class");
526 BT_ASSERT_PRE_NON_NULL(description
, "Description");
527 BT_ASSERT_PRE_COMP_CLS_HOT(comp_cls
);
528 g_string_assign(comp_cls
->description
, description
);
529 BT_LIB_LOGV("Set component class's description: "
530 "addr=%p, name=\"%s\", type=%s",
532 bt_component_class_get_name(comp_cls
),
533 bt_component_class_type_string(comp_cls
->type
));
534 return BT_COMPONENT_CLASS_STATUS_OK
;
537 bt_component_class_status
bt_component_class_set_help(
538 struct bt_component_class
*comp_cls
,
541 BT_ASSERT_PRE_NON_NULL(comp_cls
, "Component class");
542 BT_ASSERT_PRE_NON_NULL(help
, "Help");
543 BT_ASSERT_PRE_COMP_CLS_HOT(comp_cls
);
544 g_string_assign(comp_cls
->help
, help
);
545 BT_LIB_LOGV("Set component class's help text: %!+C", comp_cls
);
546 return BT_COMPONENT_CLASS_STATUS_OK
;
549 const char *bt_component_class_get_name(const struct bt_component_class
*comp_cls
)
551 BT_ASSERT_PRE_NON_NULL(comp_cls
, "Component class");
552 return comp_cls
->name
->str
;
555 enum bt_component_class_type
bt_component_class_get_type(
556 const struct bt_component_class
*comp_cls
)
558 BT_ASSERT_PRE_NON_NULL(comp_cls
, "Component class");
559 return comp_cls
->type
;
562 const char *bt_component_class_get_description(
563 const struct bt_component_class
*comp_cls
)
565 BT_ASSERT_PRE_NON_NULL(comp_cls
, "Component class");
566 return comp_cls
->description
&&
567 comp_cls
->description
->str
[0] != '\0' ?
568 comp_cls
->description
->str
: NULL
;
571 const char *bt_component_class_get_help(
572 const struct bt_component_class
*comp_cls
)
574 BT_ASSERT_PRE_NON_NULL(comp_cls
, "Component class");
575 return comp_cls
->help
&&
576 comp_cls
->help
->str
[0] != '\0' ? comp_cls
->help
->str
: NULL
;
580 void bt_component_class_add_destroy_listener(
581 struct bt_component_class
*comp_cls
,
582 bt_component_class_destroy_listener_func func
, void *data
)
584 struct bt_component_class_destroy_listener listener
;
588 listener
.func
= func
;
589 listener
.data
= data
;
590 g_array_append_val(comp_cls
->destroy_listeners
, listener
);
591 BT_LIB_LOGV("Added destroy listener to component class: "
592 "%![cc-]+C, listener-func-addr=%p", comp_cls
, func
);
596 void _bt_component_class_freeze(const struct bt_component_class
*comp_cls
)
599 BT_LIB_LOGD("Freezing component class: %!+C", comp_cls
);
600 ((struct bt_component_class
*) comp_cls
)->frozen
= true;
603 void bt_component_class_get_ref(
604 const struct bt_component_class
*component_class
)
606 bt_object_get_ref(component_class
);
609 void bt_component_class_put_ref(
610 const struct bt_component_class
*component_class
)
612 bt_object_put_ref(component_class
);
615 void bt_component_class_source_get_ref(
616 const struct bt_component_class_source
*component_class_source
)
618 bt_object_get_ref(component_class_source
);
621 void bt_component_class_source_put_ref(
622 const struct bt_component_class_source
*component_class_source
)
624 bt_object_put_ref(component_class_source
);
627 void bt_component_class_filter_get_ref(
628 const struct bt_component_class_filter
*component_class_filter
)
630 bt_object_get_ref(component_class_filter
);
633 void bt_component_class_filter_put_ref(
634 const struct bt_component_class_filter
*component_class_filter
)
636 bt_object_put_ref(component_class_filter
);
639 void bt_component_class_sink_get_ref(
640 const struct bt_component_class_sink
*component_class_sink
)
642 bt_object_get_ref(component_class_sink
);
645 void bt_component_class_sink_put_ref(
646 const struct bt_component_class_sink
*component_class_sink
)
648 bt_object_put_ref(component_class_sink
);