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-pre.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 enum bt_component_class_initialize_method_status
simple_sink_init(
38 bt_self_component_sink
*self_comp
,
39 bt_self_component_sink_configuration
*config
,
40 const struct bt_value
*params
, void *init_method_data
)
42 int status
= BT_FUNC_STATUS_OK
;
43 struct simple_sink_data
*data
= NULL
;
45 data
= g_new0(struct simple_sink_data
, 1);
47 BT_LIB_LOGE_APPEND_CAUSE(
48 "Failed to allocate simple sink component private data.");
49 status
= BT_FUNC_STATUS_MEMORY_ERROR
;
53 BT_ASSERT(init_method_data
);
54 data
->init_method_data
=
55 *((struct simple_sink_init_method_data
*) init_method_data
);
58 status
= bt_self_component_sink_add_input_port(self_comp
, "in",
60 if (status
!= BT_FUNC_STATUS_OK
) {
61 BT_LIB_LOGE_APPEND_CAUSE(
62 "Cannot add input port to simple sink component.");
66 bt_self_component_set_data(
67 bt_self_component_sink_as_self_component(self_comp
), data
);
74 void simple_sink_finalize(struct bt_self_component_sink
*self_comp
)
76 struct simple_sink_data
*data
= bt_self_component_get_data(
77 bt_self_component_sink_as_self_component(self_comp
));
80 if (data
->init_method_data
.finalize_func
) {
81 /* Call user's finalization function */
82 data
->init_method_data
.finalize_func(
83 data
->init_method_data
.user_data
);
86 BT_OBJECT_PUT_REF_AND_RESET(data
->msg_iter
);
92 enum bt_component_class_sink_graph_is_configured_method_status
93 simple_sink_graph_is_configured(
94 bt_self_component_sink
*self_comp
)
96 bt_component_class_sink_graph_is_configured_method_status status
;
97 bt_message_iterator_create_from_sink_component_status
99 struct simple_sink_data
*data
= bt_self_component_get_data(
100 bt_self_component_sink_as_self_component(self_comp
));
102 struct bt_self_component_port_input
*self_port
=
103 bt_self_component_sink_borrow_input_port_by_name(self_comp
,
106 if (!bt_port_is_connected(bt_self_component_port_as_port(
107 bt_self_component_port_input_as_self_component_port(self_port
)))) {
108 BT_LIB_LOGE_APPEND_CAUSE(
109 "Simple sink component's input port is not connected: "
110 "%![comp-]+c, %![port-]+p", self_comp
, self_port
);
111 status
= BT_COMPONENT_CLASS_SINK_GRAPH_IS_CONFIGURED_METHOD_STATUS_ERROR
;
116 msg_iter_status
= bt_message_iterator_create_from_sink_component(
117 self_comp
, self_port
, &data
->msg_iter
);
118 if (msg_iter_status
!= BT_MESSAGE_ITERATOR_CREATE_FROM_SINK_COMPONENT_STATUS_OK
) {
119 BT_LIB_LOGE_APPEND_CAUSE(
120 "Cannot create input port message iterator: "
121 "%![comp-]+c, %![port-]+p", self_comp
, self_port
);
122 status
= (int) msg_iter_status
;
126 if (data
->init_method_data
.init_func
) {
127 bt_graph_simple_sink_component_initialize_func_status init_status
;
129 /* Call user's initialization function */
130 init_status
= data
->init_method_data
.init_func(data
->msg_iter
,
131 data
->init_method_data
.user_data
);
132 if (init_status
!= BT_GRAPH_SIMPLE_SINK_COMPONENT_INITIALIZE_FUNC_STATUS_OK
) {
133 BT_LIB_LOGW_APPEND_CAUSE(
134 "Simple sink component's user's initialization function failed: "
135 "status=%s, %![comp-]+c, %![port-]+p",
136 bt_common_func_status_string(init_status
),
137 self_comp
, self_port
);
138 status
= (int) init_status
;
143 status
= BT_COMPONENT_CLASS_SINK_GRAPH_IS_CONFIGURED_METHOD_STATUS_OK
;
150 enum bt_component_class_sink_consume_method_status
simple_sink_consume(
151 struct bt_self_component_sink
*self_comp
)
154 struct simple_sink_data
*data
= bt_self_component_get_data(
155 bt_self_component_sink_as_self_component(self_comp
));
158 BT_ASSERT_DBG(data
->init_method_data
.consume_func
);
159 BT_ASSERT_DBG(data
->msg_iter
);
161 /* Call user's "consume" function */
162 status
= data
->init_method_data
.consume_func(data
->msg_iter
,
163 data
->init_method_data
.user_data
);
165 BT_LIB_LOGW_APPEND_CAUSE(
166 "Simple sink component's user's \"consume\" function failed: "
167 "status=%s, %![comp-]+c",
168 bt_common_func_status_string(status
), self_comp
);
174 struct bt_component_class_sink
*bt_component_class_sink_simple_borrow(void)
176 enum bt_component_class_set_method_status set_method_status
;
178 BT_ASSERT_PRE_NO_ERROR();
180 if (simple_comp_cls
) {
184 simple_comp_cls
= bt_component_class_sink_create("simple-sink",
185 simple_sink_consume
);
186 if (!simple_comp_cls
) {
187 BT_LIB_LOGE_APPEND_CAUSE(
188 "Cannot create simple sink component class.");
192 set_method_status
= bt_component_class_sink_set_initialize_method(
193 simple_comp_cls
, simple_sink_init
);
194 BT_ASSERT(set_method_status
== BT_FUNC_STATUS_OK
);
195 set_method_status
= bt_component_class_sink_set_finalize_method(
196 simple_comp_cls
, simple_sink_finalize
);
197 BT_ASSERT(set_method_status
== BT_FUNC_STATUS_OK
);
198 set_method_status
= bt_component_class_sink_set_graph_is_configured_method(
199 simple_comp_cls
, simple_sink_graph_is_configured
);
200 BT_ASSERT(set_method_status
== BT_FUNC_STATUS_OK
);
203 return simple_comp_cls
;
206 __attribute__((destructor
)) static
207 void put_simple_sink_component_class(void) {
208 BT_OBJECT_PUT_REF_AND_RESET(simple_comp_cls
);