4 * Babeltrace Sink Component
6 * Copyright 2015 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 #include <babeltrace/compiler.h>
30 #include <babeltrace/values.h>
31 #include <babeltrace/plugin/sink-internal.h>
32 #include <babeltrace/plugin/component-internal.h>
33 #include <babeltrace/plugin/notification/notification.h>
36 enum bt_component_status
bt_component_sink_validate(
37 struct bt_component
*component
)
39 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
40 struct bt_component_sink
*sink
;
42 sink
= container_of(component
, struct bt_component_sink
, parent
);
44 printf_error("Invalid sink component; no notification consumption callback defined.");
45 ret
= BT_COMPONENT_STATUS_INVALID
;
49 if (sink
->min_input_count
> sink
->max_input_count
) {
50 printf_error("Invalid sink component; minimum input count > maximum input count.");
51 ret
= BT_COMPONENT_STATUS_INVALID
;
59 void bt_component_sink_destroy(struct bt_component
*component
)
61 struct bt_component_sink
*sink
= container_of(component
,
62 struct bt_component_sink
, parent
);
64 g_ptr_array_free(sink
->inputs
, TRUE
);
68 struct bt_component
*bt_component_sink_create(
69 struct bt_component_class
*class, struct bt_value
*params
)
71 struct bt_component_sink
*sink
= NULL
;
72 enum bt_component_status ret
;
74 sink
= g_new0(struct bt_component_sink
, 1);
79 sink
->parent
.class = bt_get(class);
80 ret
= bt_component_init(&sink
->parent
, bt_component_sink_destroy
);
81 if (ret
!= BT_COMPONENT_STATUS_OK
) {
85 sink
->min_input_count
= 1;
86 sink
->max_input_count
= 1;
88 ret = bt_component_sink_register_notification_type(&sink->parent,
89 BT_NOTIFICATION_TYPE_EVENT);
90 if (ret != BT_COMPONENT_STATUS_OK) {
94 sink
->inputs
= g_ptr_array_new_with_free_func(bt_put
);
99 return sink
? &sink
->parent
: NULL
;
106 enum bt_component_status
validate_inputs(struct bt_component_sink
*sink
)
108 size_t array_size
= sink
->inputs
->len
;
110 if (array_size
< sink
->min_input_count
||
111 array_size
> sink
->max_input_count
) {
112 return BT_COMPONENT_STATUS_INVALID
;
115 return BT_COMPONENT_STATUS_OK
;
118 enum bt_component_status
bt_component_sink_consume(
119 struct bt_component
*component
)
121 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
122 struct bt_component_sink
*sink
= NULL
;
125 ret
= BT_COMPONENT_STATUS_INVALID
;
129 if (bt_component_get_type(component
) != BT_COMPONENT_TYPE_SINK
) {
130 ret
= BT_COMPONENT_STATUS_UNSUPPORTED
;
134 sink
= container_of(component
, struct bt_component_sink
, parent
);
135 if (!sink
->validated_inputs
) {
136 ret
= validate_inputs(sink
);
137 if (ret
!= BT_COMPONENT_STATUS_OK
) {
140 sink
->validated_inputs
= true;
143 assert(sink
->consume
);
144 ret
= sink
->consume(component
);
150 enum bt_component_status bt_component_sink_register_notification_type(
151 struct bt_component *component, enum bt_notification_type type)
153 enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
154 struct bt_component_sink *sink = NULL;
157 ret = BT_COMPONENT_STATUS_INVALID;
161 if (bt_component_get_type(component) != BT_COMPONENT_TYPE_SINK) {
162 ret = BT_COMPONENT_STATUS_UNSUPPORTED;
166 if (type <= BT_NOTIFICATION_TYPE_UNKNOWN ||
167 type >= BT_NOTIFICATION_TYPE_NR) {
168 ret = BT_COMPONENT_STATUS_INVALID;
171 sink = container_of(component, struct bt_component_sink, parent);
172 if (type == BT_NOTIFICATION_TYPE_ALL) {
173 sink->registered_notifications_mask = ~(notification_mask_t) 0;
175 sink->registered_notifications_mask |=
176 (notification_mask_t) 1 << type;
182 enum bt_component_status
bt_component_sink_set_consume_cb(
183 struct bt_component
*component
,
184 bt_component_sink_consume_cb consume
)
186 struct bt_component_sink
*sink
;
187 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
190 ret
= BT_COMPONENT_STATUS_INVALID
;
194 if (bt_component_get_type(component
) != BT_COMPONENT_TYPE_SINK
) {
195 ret
= BT_COMPONENT_STATUS_UNSUPPORTED
;
199 if (!component
->initializing
) {
200 ret
= BT_COMPONENT_STATUS_INVALID
;
204 sink
= container_of(component
, struct bt_component_sink
, parent
);
205 sink
->consume
= consume
;
210 enum bt_component_status
bt_component_sink_set_minimum_input_count(
211 struct bt_component
*component
,
212 unsigned int minimum
)
214 struct bt_component_sink
*sink
;
215 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
218 ret
= BT_COMPONENT_STATUS_INVALID
;
222 if (bt_component_get_type(component
) != BT_COMPONENT_TYPE_SINK
) {
223 ret
= BT_COMPONENT_STATUS_UNSUPPORTED
;
227 if (!component
->initializing
) {
228 ret
= BT_COMPONENT_STATUS_INVALID
;
232 sink
= container_of(component
, struct bt_component_sink
, parent
);
233 sink
->min_input_count
= minimum
;
238 enum bt_component_status
bt_component_sink_set_maximum_input_count(
239 struct bt_component
*component
,
240 unsigned int maximum
)
242 struct bt_component_sink
*sink
;
243 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
246 ret
= BT_COMPONENT_STATUS_INVALID
;
250 if (bt_component_get_type(component
) != BT_COMPONENT_TYPE_SINK
) {
251 ret
= BT_COMPONENT_STATUS_UNSUPPORTED
;
255 if (!component
->initializing
) {
256 ret
= BT_COMPONENT_STATUS_INVALID
;
260 sink
= container_of(component
, struct bt_component_sink
, parent
);
261 sink
->max_input_count
= maximum
;
266 enum bt_component_status
267 bt_component_sink_get_input_count(struct bt_component
*component
,
270 struct bt_component_sink
*sink
;
271 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
273 if (!component
|| !count
) {
274 ret
= BT_COMPONENT_STATUS_INVALID
;
278 if (bt_component_get_type(component
) != BT_COMPONENT_TYPE_SINK
) {
279 ret
= BT_COMPONENT_STATUS_UNSUPPORTED
;
283 sink
= container_of(component
, struct bt_component_sink
, parent
);
284 *count
= (unsigned int) sink
->inputs
->len
;
289 enum bt_component_status
290 bt_component_sink_get_input_iterator(struct bt_component
*component
,
291 unsigned int input
, struct bt_notification_iterator
**iterator
)
293 struct bt_component_sink
*sink
;
294 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
296 if (!component
|| !iterator
) {
297 ret
= BT_COMPONENT_STATUS_INVALID
;
301 if (bt_component_get_type(component
) != BT_COMPONENT_TYPE_SINK
) {
302 ret
= BT_COMPONENT_STATUS_UNSUPPORTED
;
306 sink
= container_of(component
, struct bt_component_sink
, parent
);
307 if (input
>= (unsigned int) sink
->inputs
->len
) {
308 ret
= BT_COMPONENT_STATUS_INVALID
;
312 *iterator
= bt_get(g_ptr_array_index(sink
->inputs
, input
));
317 enum bt_component_status
318 bt_component_sink_add_iterator(struct bt_component
*component
,
319 struct bt_notification_iterator
*iterator
)
321 struct bt_component_sink
*sink
;
322 enum bt_component_status ret
= BT_COMPONENT_STATUS_OK
;
324 if (!component
|| !iterator
) {
325 ret
= BT_COMPONENT_STATUS_INVALID
;
329 if (bt_component_get_type(component
) != BT_COMPONENT_TYPE_SINK
) {
330 ret
= BT_COMPONENT_STATUS_UNSUPPORTED
;
334 sink
= container_of(component
, struct bt_component_sink
, parent
);
335 if (sink
->inputs
->len
== sink
->max_input_count
) {
336 ret
= BT_COMPONENT_STATUS_UNSUPPORTED
;
340 if (sink
->add_iterator
) {
341 ret
= sink
->add_iterator(component
, iterator
);
342 if (ret
!= BT_COMPONENT_STATUS_OK
) {
347 g_ptr_array_add(sink
->inputs
, bt_get(iterator
));