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
,
49 const struct bt_value
*params
, void *init_method_data
)
51 int status
= BT_FUNC_STATUS_OK
;
52 struct simple_sink_data
*data
= NULL
;
54 data
= g_new0(struct simple_sink_data
, 1);
56 BT_LIB_LOGE_APPEND_CAUSE(
57 "Failed to allocate simple sink component private data.");
58 status
= BT_FUNC_STATUS_MEMORY_ERROR
;
62 BT_ASSERT(init_method_data
);
63 data
->init_method_data
=
64 *((struct simple_sink_init_method_data
*) init_method_data
);
67 status
= bt_self_component_sink_add_input_port(self_comp
, "in",
69 if (status
!= BT_FUNC_STATUS_OK
) {
70 BT_LIB_LOGE_APPEND_CAUSE(
71 "Cannot add input port to simple sink component.");
75 /* Transfer ownership to component */
76 bt_self_component_set_data(
77 bt_self_component_sink_as_self_component(self_comp
), data
);
81 simple_sink_data_destroy(data
);
86 void simple_sink_finalize(struct bt_self_component_sink
*self_comp
)
88 struct simple_sink_data
*data
= bt_self_component_get_data(
89 bt_self_component_sink_as_self_component(self_comp
));
93 if (data
->init_method_data
.finalize_func
) {
94 /* Call user's finalization function */
95 data
->init_method_data
.finalize_func(
96 data
->init_method_data
.user_data
);
99 simple_sink_data_destroy(data
);
103 enum bt_component_class_sink_graph_is_configured_method_status
104 simple_sink_graph_is_configured(
105 bt_self_component_sink
*self_comp
)
107 bt_component_class_sink_graph_is_configured_method_status status
;
108 bt_message_iterator_create_from_sink_component_status
110 struct simple_sink_data
*data
= bt_self_component_get_data(
111 bt_self_component_sink_as_self_component(self_comp
));
113 struct bt_self_component_port_input
*self_port
=
114 bt_self_component_sink_borrow_input_port_by_name(self_comp
,
117 if (!bt_port_is_connected(bt_self_component_port_as_port(
118 bt_self_component_port_input_as_self_component_port(self_port
)))) {
119 BT_LIB_LOGE_APPEND_CAUSE(
120 "Simple sink component's input port is not connected: "
121 "%![comp-]+c, %![port-]+p", self_comp
, self_port
);
122 status
= BT_COMPONENT_CLASS_SINK_GRAPH_IS_CONFIGURED_METHOD_STATUS_ERROR
;
127 msg_iter_status
= bt_message_iterator_create_from_sink_component(
128 self_comp
, self_port
, &data
->msg_iter
);
129 if (msg_iter_status
!= BT_MESSAGE_ITERATOR_CREATE_FROM_SINK_COMPONENT_STATUS_OK
) {
130 BT_LIB_LOGE_APPEND_CAUSE(
131 "Cannot create input port message iterator: "
132 "%![comp-]+c, %![port-]+p", self_comp
, self_port
);
133 status
= (int) msg_iter_status
;
137 if (data
->init_method_data
.init_func
) {
138 bt_graph_simple_sink_component_initialize_func_status init_status
;
140 /* Call user's initialization function */
141 init_status
= data
->init_method_data
.init_func(data
->msg_iter
,
142 data
->init_method_data
.user_data
);
143 if (init_status
!= BT_GRAPH_SIMPLE_SINK_COMPONENT_INITIALIZE_FUNC_STATUS_OK
) {
144 BT_LIB_LOGW_APPEND_CAUSE(
145 "Simple sink component's user's initialization function failed: "
146 "status=%s, %![comp-]+c, %![port-]+p",
147 bt_common_func_status_string(init_status
),
148 self_comp
, self_port
);
149 status
= (int) init_status
;
154 status
= BT_COMPONENT_CLASS_SINK_GRAPH_IS_CONFIGURED_METHOD_STATUS_OK
;
161 enum bt_component_class_sink_consume_method_status
simple_sink_consume(
162 struct bt_self_component_sink
*self_comp
)
165 struct simple_sink_data
*data
= bt_self_component_get_data(
166 bt_self_component_sink_as_self_component(self_comp
));
169 BT_ASSERT_DBG(data
->init_method_data
.consume_func
);
170 BT_ASSERT_DBG(data
->msg_iter
);
172 /* Call user's "consume" function */
173 status
= data
->init_method_data
.consume_func(data
->msg_iter
,
174 data
->init_method_data
.user_data
);
176 BT_LIB_LOGW_APPEND_CAUSE(
177 "Simple sink component's user's \"consume\" function failed: "
178 "status=%s, %![comp-]+c",
179 bt_common_func_status_string(status
), self_comp
);
185 struct bt_component_class_sink
*bt_component_class_sink_simple_borrow(void)
187 enum bt_component_class_set_method_status set_method_status
;
189 if (simple_comp_cls
) {
193 simple_comp_cls
= bt_component_class_sink_create("simple-sink",
194 simple_sink_consume
);
195 if (!simple_comp_cls
) {
196 BT_LIB_LOGE_APPEND_CAUSE(
197 "Cannot create simple sink component class.");
201 set_method_status
= bt_component_class_sink_set_initialize_method(
202 simple_comp_cls
, simple_sink_init
);
203 BT_ASSERT(set_method_status
== BT_FUNC_STATUS_OK
);
204 set_method_status
= bt_component_class_sink_set_finalize_method(
205 simple_comp_cls
, simple_sink_finalize
);
206 BT_ASSERT(set_method_status
== BT_FUNC_STATUS_OK
);
207 set_method_status
= bt_component_class_sink_set_graph_is_configured_method(
208 simple_comp_cls
, simple_sink_graph_is_configured
);
209 BT_ASSERT(set_method_status
== BT_FUNC_STATUS_OK
);
212 return simple_comp_cls
;
215 __attribute__((destructor
)) static
216 void put_simple_sink_component_class(void) {
217 BT_OBJECT_PUT_REF_AND_RESET(simple_comp_cls
);