2 * SPDX-License-Identifier: MIT
4 * Copyright 2017-2019 Philippe Proulx <pproulx@efficios.com>
7 #define BT_LOG_TAG "LIB/COMPONENT-CLASS-SINK-SIMPLE"
8 #include "lib/logging.h"
10 #include "common/assert.h"
11 #include "common/common.h"
12 #include "lib/assert-cond.h"
13 #include "lib/object.h"
14 #include <babeltrace2/graph/component-class.h>
15 #include <babeltrace2/graph/self-component-port.h>
16 #include <babeltrace2/graph/self-component.h>
17 #include <babeltrace2/graph/message-iterator.h>
20 #include "component-class-sink-simple.h"
21 #include "lib/func-status.h"
24 * We keep a single simple sink component class reference. It's created
25 * the first time bt_component_class_sink_simple_borrow() is called and
26 * put by the put_simple_sink_component_class() library destructor.
29 struct bt_component_class_sink
*simple_comp_cls
;
31 struct simple_sink_data
{
32 bt_message_iterator
*msg_iter
;
33 struct simple_sink_init_method_data init_method_data
;
37 void simple_sink_data_destroy(struct simple_sink_data
*data
)
40 BT_OBJECT_PUT_REF_AND_RESET(data
->msg_iter
);
46 enum bt_component_class_initialize_method_status
simple_sink_init(
47 bt_self_component_sink
*self_comp
,
48 bt_self_component_sink_configuration
*config
__attribute__((unused
)),
49 const struct bt_value
*params
__attribute__((unused
)),
50 void *init_method_data
)
52 int status
= BT_FUNC_STATUS_OK
;
53 struct simple_sink_data
*data
= NULL
;
55 data
= g_new0(struct simple_sink_data
, 1);
57 BT_LIB_LOGE_APPEND_CAUSE(
58 "Failed to allocate simple sink component private data.");
59 status
= BT_FUNC_STATUS_MEMORY_ERROR
;
63 BT_ASSERT(init_method_data
);
64 data
->init_method_data
=
65 *((struct simple_sink_init_method_data
*) init_method_data
);
68 status
= bt_self_component_sink_add_input_port(self_comp
, "in",
70 if (status
!= BT_FUNC_STATUS_OK
) {
71 BT_LIB_LOGE_APPEND_CAUSE(
72 "Cannot add input port to simple sink component.");
76 /* Transfer ownership to component */
77 bt_self_component_set_data(
78 bt_self_component_sink_as_self_component(self_comp
), data
);
82 simple_sink_data_destroy(data
);
87 void simple_sink_finalize(struct bt_self_component_sink
*self_comp
)
89 struct simple_sink_data
*data
= bt_self_component_get_data(
90 bt_self_component_sink_as_self_component(self_comp
));
94 if (data
->init_method_data
.finalize_func
) {
95 /* Call user's finalization function */
96 data
->init_method_data
.finalize_func(
97 data
->init_method_data
.user_data
);
100 simple_sink_data_destroy(data
);
104 enum bt_component_class_sink_graph_is_configured_method_status
105 simple_sink_graph_is_configured(
106 bt_self_component_sink
*self_comp
)
108 bt_component_class_sink_graph_is_configured_method_status status
;
109 bt_message_iterator_create_from_sink_component_status
111 struct simple_sink_data
*data
= bt_self_component_get_data(
112 bt_self_component_sink_as_self_component(self_comp
));
114 struct bt_self_component_port_input
*self_port
=
115 bt_self_component_sink_borrow_input_port_by_name(self_comp
,
118 if (!bt_port_is_connected(bt_self_component_port_as_port(
119 bt_self_component_port_input_as_self_component_port(self_port
)))) {
120 BT_LIB_LOGE_APPEND_CAUSE(
121 "Simple sink component's input port is not connected: "
122 "%![comp-]+c, %![port-]+p", self_comp
, self_port
);
123 status
= BT_COMPONENT_CLASS_SINK_GRAPH_IS_CONFIGURED_METHOD_STATUS_ERROR
;
128 msg_iter_status
= bt_message_iterator_create_from_sink_component(
129 self_comp
, self_port
, &data
->msg_iter
);
130 if (msg_iter_status
!= BT_MESSAGE_ITERATOR_CREATE_FROM_SINK_COMPONENT_STATUS_OK
) {
131 BT_LIB_LOGE_APPEND_CAUSE(
132 "Cannot create input port message iterator: "
133 "%![comp-]+c, %![port-]+p", self_comp
, self_port
);
134 status
= (int) msg_iter_status
;
138 if (data
->init_method_data
.init_func
) {
139 bt_graph_simple_sink_component_initialize_func_status init_status
;
141 /* Call user's initialization function */
142 init_status
= data
->init_method_data
.init_func(data
->msg_iter
,
143 data
->init_method_data
.user_data
);
144 if (init_status
!= BT_GRAPH_SIMPLE_SINK_COMPONENT_INITIALIZE_FUNC_STATUS_OK
) {
145 BT_LIB_LOGW_APPEND_CAUSE(
146 "Simple sink component's user's initialization function failed: "
147 "status=%s, %![comp-]+c, %![port-]+p",
148 bt_common_func_status_string(init_status
),
149 self_comp
, self_port
);
150 status
= (int) init_status
;
155 status
= BT_COMPONENT_CLASS_SINK_GRAPH_IS_CONFIGURED_METHOD_STATUS_OK
;
162 enum bt_component_class_sink_consume_method_status
simple_sink_consume(
163 struct bt_self_component_sink
*self_comp
)
166 struct simple_sink_data
*data
= bt_self_component_get_data(
167 bt_self_component_sink_as_self_component(self_comp
));
170 BT_ASSERT_DBG(data
->init_method_data
.consume_func
);
171 BT_ASSERT_DBG(data
->msg_iter
);
173 /* Call user's "consume" function */
174 status
= data
->init_method_data
.consume_func(data
->msg_iter
,
175 data
->init_method_data
.user_data
);
177 BT_LIB_LOGW_APPEND_CAUSE(
178 "Simple sink component's user's \"consume\" function failed: "
179 "status=%s, %![comp-]+c",
180 bt_common_func_status_string(status
), self_comp
);
186 struct bt_component_class_sink
*bt_component_class_sink_simple_borrow(void)
188 enum bt_component_class_set_method_status set_method_status
;
190 if (simple_comp_cls
) {
194 simple_comp_cls
= bt_component_class_sink_create("simple-sink",
195 simple_sink_consume
);
196 if (!simple_comp_cls
) {
197 BT_LIB_LOGE_APPEND_CAUSE(
198 "Cannot create simple sink component class.");
202 set_method_status
= bt_component_class_sink_set_initialize_method(
203 simple_comp_cls
, simple_sink_init
);
204 BT_ASSERT(set_method_status
== BT_FUNC_STATUS_OK
);
205 set_method_status
= bt_component_class_sink_set_finalize_method(
206 simple_comp_cls
, simple_sink_finalize
);
207 BT_ASSERT(set_method_status
== BT_FUNC_STATUS_OK
);
208 set_method_status
= bt_component_class_sink_set_graph_is_configured_method(
209 simple_comp_cls
, simple_sink_graph_is_configured
);
210 BT_ASSERT(set_method_status
== BT_FUNC_STATUS_OK
);
213 return simple_comp_cls
;
216 __attribute__((destructor
)) static
217 void put_simple_sink_component_class(void) {
218 BT_OBJECT_PUT_REF_AND_RESET(simple_comp_cls
);