Logging: standardize logging tags
[babeltrace.git] / src / lib / graph / component.c
CommitLineData
de713ce0 1/*
e2f7325d 2 * Copyright 2017-2018 Philippe Proulx <pproulx@efficios.com>
de713ce0
JG
3 * Copyright 2015 Jérémie Galarneau <jeremie.galarneau@efficios.com>
4 *
de713ce0
JG
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:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
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
21 * SOFTWARE.
22 */
23
350ad6c1 24#define BT_LOG_TAG "LIB/COMPONENT"
578e048b 25#include "lib/lib-logging.h"
ab0d387b 26
578e048b
MJ
27#include "common/assert.h"
28#include "lib/assert-pre.h"
3fadfbc0
MJ
29#include <babeltrace2/graph/self-component.h>
30#include <babeltrace2/graph/component-const.h>
31#include <babeltrace2/graph/component-source-const.h>
32#include <babeltrace2/graph/component-filter-const.h>
33#include <babeltrace2/graph/component-sink-const.h>
91d81473 34#include "common/macros.h"
578e048b 35#include "compat/compiler.h"
3fadfbc0
MJ
36#include <babeltrace2/types.h>
37#include <babeltrace2/value.h>
578e048b 38#include "lib/value.h"
9ac68eb1 39#include <stdint.h>
ab0d387b 40#include <inttypes.h>
de713ce0 41
578e048b
MJ
42#include "component.h"
43#include "component-class.h"
44#include "component-source.h"
45#include "component-filter.h"
46#include "component-sink.h"
47#include "connection.h"
48#include "graph.h"
49#include "message/iterator.h"
50#include "port.h"
51
7c7c0433
JG
52static
53struct bt_component * (* const component_create_funcs[])(
0d72b8c3 54 const struct bt_component_class *) = {
d3e4dcd8
PP
55 [BT_COMPONENT_CLASS_TYPE_SOURCE] = bt_component_source_create,
56 [BT_COMPONENT_CLASS_TYPE_SINK] = bt_component_sink_create,
57 [BT_COMPONENT_CLASS_TYPE_FILTER] = bt_component_filter_create,
7c7c0433
JG
58};
59
72b913fb
PP
60static
61void (*component_destroy_funcs[])(struct bt_component *) = {
62 [BT_COMPONENT_CLASS_TYPE_SOURCE] = bt_component_source_destroy,
63 [BT_COMPONENT_CLASS_TYPE_SINK] = bt_component_sink_destroy,
64 [BT_COMPONENT_CLASS_TYPE_FILTER] = bt_component_filter_destroy,
65};
66
b8a06801 67static
d94d92ac
PP
68void finalize_component(struct bt_component *comp)
69{
70 typedef void (*method_t)(void *);
71
72 method_t method = NULL;
73
74 BT_ASSERT(comp);
75
76 switch (comp->class->type) {
77 case BT_COMPONENT_CLASS_TYPE_SOURCE:
78 {
79 struct bt_component_class_source *src_cc = (void *) comp->class;
80
81 method = (method_t) src_cc->methods.finalize;
82 break;
83 }
84 case BT_COMPONENT_CLASS_TYPE_FILTER:
85 {
86 struct bt_component_class_filter *flt_cc = (void *) comp->class;
87
88 method = (method_t) flt_cc->methods.finalize;
89 break;
90 }
91 case BT_COMPONENT_CLASS_TYPE_SINK:
92 {
93 struct bt_component_class_sink *sink_cc = (void *) comp->class;
94
95 method = (method_t) sink_cc->methods.finalize;
96 break;
97 }
98 default:
99 abort();
100 }
101
102 if (method) {
3f7d4d90 103 BT_LIB_LOGI("Calling user's component finalization method: "
d94d92ac
PP
104 "%![comp-]+c", comp);
105 method(comp);
106 }
107}
108
109static
110void destroy_component(struct bt_object *obj)
b8a06801
JG
111{
112 struct bt_component *component = NULL;
3230ee6b 113 int i;
b8a06801
JG
114
115 if (!obj) {
116 return;
117 }
118
bd14d768
PP
119 /*
120 * The component's reference count is 0 if we're here. Increment
121 * it to avoid a double-destroy (possibly infinitely recursive).
122 * This could happen for example if the component's finalization
d94d92ac
PP
123 * function does bt_object_get_ref() (or anything that causes
124 * bt_object_get_ref() to be called) on itself (ref. count goes
125 * from 0 to 1), and then bt_object_put_ref(): the reference
126 * count would go from 1 to 0 again and this function would be
127 * called again.
bd14d768 128 */
3fea54f6 129 obj->ref_count++;
b8a06801 130 component = container_of(obj, struct bt_component, base);
3f7d4d90 131 BT_LIB_LOGI("Destroying component: %![comp-]+c, %![graph-]+g",
d94d92ac 132 component, bt_component_borrow_graph(component));
3230ee6b
PP
133
134 /* Call destroy listeners in reverse registration order */
ab0d387b
PP
135 BT_LOGD_STR("Calling destroy listeners.");
136
3230ee6b
PP
137 for (i = component->destroy_listeners->len - 1; i >= 0; i--) {
138 struct bt_component_destroy_listener *listener =
139 &g_array_index(component->destroy_listeners,
140 struct bt_component_destroy_listener, i);
141
142 listener->func(component, listener->data);
143 }
144
7c7c0433 145 /*
36712f1d
PP
146 * User data is destroyed first, followed by the concrete
147 * component instance. Do not finalize if the component's user
148 * initialization method failed in the first place.
b8a06801 149 */
d94d92ac
PP
150 if (component->initialized) {
151 finalize_component(component);
7c7c0433 152 }
b8a06801 153
ab09f844 154 if (component->destroy) {
ab0d387b 155 BT_LOGD_STR("Destroying type-specific data.");
ab09f844
JG
156 component->destroy(component);
157 }
158
72b913fb 159 if (component->input_ports) {
ab0d387b 160 BT_LOGD_STR("Destroying input ports.");
72b913fb 161 g_ptr_array_free(component->input_ports, TRUE);
d94d92ac 162 component->input_ports = NULL;
72b913fb 163 }
b8a06801 164
72b913fb 165 if (component->output_ports) {
ab0d387b 166 BT_LOGD_STR("Destroying output ports.");
72b913fb 167 g_ptr_array_free(component->output_ports, TRUE);
d94d92ac 168 component->output_ports = NULL;
b8a06801
JG
169 }
170
3230ee6b
PP
171 if (component->destroy_listeners) {
172 g_array_free(component->destroy_listeners, TRUE);
d94d92ac 173 component->destroy_listeners = NULL;
3230ee6b
PP
174 }
175
ab0d387b
PP
176 if (component->name) {
177 g_string_free(component->name, TRUE);
d94d92ac 178 component->name = NULL;
ab0d387b
PP
179 }
180
d94d92ac
PP
181 BT_LOGD_STR("Putting component class.");
182 BT_OBJECT_PUT_REF_AND_RESET(component->class);
72b913fb 183 g_free(component);
b8a06801 184}
de713ce0 185
890882ef 186enum bt_component_class_type bt_component_get_class_type(
0d72b8c3 187 const struct bt_component *component)
5645cd95 188{
d94d92ac
PP
189 BT_ASSERT_PRE_NON_NULL(component, "Component");
190 return component->class->type;
5645cd95
JG
191}
192
72b913fb 193static
8cc56726 194enum bt_self_component_status add_port(
72b913fb 195 struct bt_component *component, GPtrArray *ports,
8cc56726
SM
196 enum bt_port_type port_type, const char *name, void *user_data,
197 struct bt_port **port)
72b913fb 198{
72b913fb 199 struct bt_port *new_port = NULL;
1bf957a0 200 struct bt_graph *graph = NULL;
8cc56726 201 enum bt_self_component_status status;
72b913fb 202
d94d92ac
PP
203 BT_ASSERT_PRE_NON_NULL(component, "Component");
204 BT_ASSERT_PRE_NON_NULL(name, "Name");
205 BT_ASSERT_PRE(strlen(name) > 0, "Name is empty");
206 graph = bt_component_borrow_graph(component);
207 BT_ASSERT_PRE(graph && !bt_graph_is_canceled(graph),
208 "Component's graph is canceled: %![comp-]+c, %![graph-]+g",
209 component, graph);
5badd463
PP
210 BT_ASSERT_PRE(
211 graph->config_state == BT_GRAPH_CONFIGURATION_STATE_CONFIGURING,
4725a201
PP
212 "Component's graph is already configured: "
213 "%![comp-]+c, %![graph-]+g", component, graph);
72b913fb 214
d94d92ac 215 // TODO: Validate that the name is not already used.
ab0d387b 216
3f7d4d90 217 BT_LIB_LOGI("Adding port to component: %![comp-]+c, "
ab0d387b 218 "port-type=%s, port-name=\"%s\"", component,
ab0d387b
PP
219 bt_port_type_string(port_type), name);
220
3e9b0023 221 new_port = bt_port_create(component, port_type, name, user_data);
72b913fb 222 if (!new_port) {
d94d92ac 223 BT_LOGE_STR("Cannot create port object.");
8cc56726
SM
224 status = BT_SELF_COMPONENT_STATUS_NOMEM;
225 goto error;
72b913fb
PP
226 }
227
228 /*
229 * No name clash, add the port.
230 * The component is now the port's parent; it should _not_
231 * hold a reference to the port since the port's lifetime
232 * is now protected by the component's own lifetime.
233 */
234 g_ptr_array_add(ports, new_port);
1bf957a0
PP
235
236 /*
237 * Notify the graph's creator that a new port was added.
238 */
398454ed 239 graph = bt_component_borrow_graph(component);
1bf957a0 240 if (graph) {
8cc56726
SM
241 enum bt_graph_listener_status listener_status;
242
243 listener_status = bt_graph_notify_port_added(graph, new_port);
244 if (listener_status != BT_GRAPH_LISTENER_STATUS_OK) {
245 bt_graph_make_faulty(graph);
246 status = listener_status;
247 goto error;
248 }
1bf957a0
PP
249 }
250
3f7d4d90 251 BT_LIB_LOGI("Created and added port to component: "
d94d92ac 252 "%![comp-]+c, %![port-]+p", component, new_port);
ab0d387b 253
8cc56726
SM
254 *port = new_port;
255 status = BT_SELF_COMPONENT_STATUS_OK;
256
257 goto end;
258error:
259 /*
260 * We need to release the reference that we would otherwise have
261 * returned to the caller.
262 */
263 BT_PORT_PUT_REF_AND_RESET(new_port);
264
72b913fb 265end:
8cc56726 266 return status;
72b913fb
PP
267}
268
269BT_HIDDEN
0d72b8c3 270uint64_t bt_component_get_input_port_count(const struct bt_component *comp)
72b913fb 271{
d94d92ac
PP
272 BT_ASSERT_PRE_NON_NULL(comp, "Component");
273 return (uint64_t) comp->input_ports->len;
72b913fb
PP
274}
275
276BT_HIDDEN
0d72b8c3 277uint64_t bt_component_get_output_port_count(const struct bt_component *comp)
72b913fb 278{
d94d92ac
PP
279 BT_ASSERT_PRE_NON_NULL(comp, "Component");
280 return (uint64_t) comp->output_ports->len;
72b913fb
PP
281}
282
dd8a4547 283BT_HIDDEN
d94d92ac 284int bt_component_create(struct bt_component_class *component_class,
36712f1d 285 const char *name, struct bt_component **user_component)
38b48196 286{
d94d92ac 287 int ret = 0;
38b48196 288 struct bt_component *component = NULL;
d3e4dcd8 289 enum bt_component_class_type type;
38b48196 290
f6ccaed9
PP
291 BT_ASSERT(user_component);
292 BT_ASSERT(component_class);
293 BT_ASSERT(name);
7c7c0433 294 type = bt_component_class_get_type(component_class);
3f7d4d90 295 BT_LIB_LOGI("Creating empty component from component class: %![cc-]+C, "
d94d92ac 296 "comp-name=\"%s\"", component_class, name);
36712f1d 297 component = component_create_funcs[type](component_class);
7c7c0433 298 if (!component) {
ab0d387b 299 BT_LOGE_STR("Cannot create specific component object.");
d94d92ac 300 ret = -1;
7c7c0433
JG
301 goto end;
302 }
303
d0fea130 304 bt_object_init_shared_with_parent(&component->base, destroy_component);
398454ed
PP
305 component->class = component_class;
306 bt_object_get_no_null_check(component->class);
72b913fb 307 component->destroy = component_destroy_funcs[type];
7c7c0433 308 component->name = g_string_new(name);
4b70dd83 309 if (!component->name) {
ab0d387b 310 BT_LOGE_STR("Failed to allocate one GString.");
d94d92ac 311 ret = -1;
7c7c0433
JG
312 goto end;
313 }
314
72b913fb 315 component->input_ports = g_ptr_array_new_with_free_func(
3fea54f6 316 (GDestroyNotify) bt_object_try_spec_release);
72b913fb 317 if (!component->input_ports) {
ab0d387b 318 BT_LOGE_STR("Failed to allocate one GPtrArray.");
d94d92ac 319 ret = -1;
72b913fb
PP
320 goto end;
321 }
322
323 component->output_ports = g_ptr_array_new_with_free_func(
3fea54f6 324 (GDestroyNotify) bt_object_try_spec_release);
72b913fb 325 if (!component->output_ports) {
ab0d387b 326 BT_LOGE_STR("Failed to allocate one GPtrArray.");
d94d92ac 327 ret = -1;
72b913fb
PP
328 goto end;
329 }
330
3230ee6b
PP
331 component->destroy_listeners = g_array_new(FALSE, TRUE,
332 sizeof(struct bt_component_destroy_listener));
333 if (!component->destroy_listeners) {
ab0d387b 334 BT_LOGE_STR("Failed to allocate one GArray.");
d94d92ac 335 ret = -1;
3230ee6b
PP
336 goto end;
337 }
338
3f7d4d90 339 BT_LIB_LOGI("Created empty component from component class: "
d94d92ac 340 "%![cc-]+C, %![comp-]+c", component_class, component);
65300d60 341 BT_OBJECT_MOVE_REF(*user_component, component);
ab0d387b 342
38b48196 343end:
65300d60 344 bt_object_put_ref(component);
d94d92ac 345 return ret;
6358c163
PP
346}
347
0d72b8c3 348const char *bt_component_get_name(const struct bt_component *component)
de713ce0 349{
d94d92ac
PP
350 BT_ASSERT_PRE_NON_NULL(component, "Component");
351 return component->name->str;
de713ce0
JG
352}
353
1de6a2b0 354const struct bt_component_class *bt_component_borrow_class_const(
0d72b8c3 355 const struct bt_component *component)
de713ce0 356{
d94d92ac
PP
357 BT_ASSERT_PRE_NON_NULL(component, "Component");
358 return component->class;
de713ce0
JG
359}
360
0d72b8c3 361void *bt_self_component_get_data(const struct bt_self_component *self_comp)
de713ce0 362{
d94d92ac 363 struct bt_component *component = (void *) self_comp;
890882ef 364
d94d92ac
PP
365 BT_ASSERT_PRE_NON_NULL(component, "Component");
366 return component->user_data;
de713ce0
JG
367}
368
d94d92ac 369void bt_self_component_set_data(struct bt_self_component *self_comp,
de713ce0
JG
370 void *data)
371{
d94d92ac 372 struct bt_component *component = (void *) self_comp;
ab0d387b 373
d94d92ac 374 BT_ASSERT_PRE_NON_NULL(component, "Component");
de713ce0 375 component->user_data = data;
3f7d4d90 376 BT_LIB_LOGD("Set component's user data: %!+c", component);
de713ce0 377}
366e034f
JG
378
379BT_HIDDEN
f60c8b34 380void bt_component_set_graph(struct bt_component *component,
366e034f
JG
381 struct bt_graph *graph)
382{
3fea54f6
PP
383 bt_object_set_parent(&component->base,
384 graph ? &graph->base : NULL);
366e034f
JG
385}
386
0d72b8c3 387bt_bool bt_component_graph_is_canceled(const struct bt_component *component)
366e034f 388{
e5be10ef
PP
389 return bt_graph_is_canceled(
390 (void *) bt_object_borrow_parent(&component->base));
366e034f
JG
391}
392
72b913fb 393static
d94d92ac 394struct bt_port *borrow_port_by_name(GPtrArray *ports,
9ac68eb1 395 const char *name)
366e034f 396{
d94d92ac 397 uint64_t i;
366e034f
JG
398 struct bt_port *ret_port = NULL;
399
f6ccaed9 400 BT_ASSERT(name);
72b913fb 401
366e034f
JG
402 for (i = 0; i < ports->len; i++) {
403 struct bt_port *port = g_ptr_array_index(ports, i);
366e034f 404
d94d92ac
PP
405 if (!strcmp(name, port->name->str)) {
406 ret_port = port;
366e034f
JG
407 break;
408 }
409 }
410
411 return ret_port;
412}
413
414BT_HIDDEN
d94d92ac
PP
415struct bt_port_input *bt_component_borrow_input_port_by_name(
416 struct bt_component *comp, const char *name)
72b913fb 417{
f6ccaed9 418 BT_ASSERT(comp);
d94d92ac 419 return (void *) borrow_port_by_name(comp->input_ports, name);
72b913fb
PP
420}
421
422BT_HIDDEN
d94d92ac
PP
423struct bt_port_output *bt_component_borrow_output_port_by_name(
424 struct bt_component *comp, const char *name)
72b913fb 425{
d94d92ac
PP
426 BT_ASSERT_PRE_NON_NULL(comp, "Component");
427 return (void *)
428 borrow_port_by_name(comp->output_ports, name);
72b913fb
PP
429}
430
431static
d94d92ac 432struct bt_port *borrow_port_by_index(GPtrArray *ports, uint64_t index)
366e034f 433{
d94d92ac
PP
434 BT_ASSERT(index < ports->len);
435 return g_ptr_array_index(ports, index);
366e034f
JG
436}
437
438BT_HIDDEN
d94d92ac
PP
439struct bt_port_input *bt_component_borrow_input_port_by_index(
440 struct bt_component *comp, uint64_t index)
366e034f 441{
d94d92ac
PP
442 BT_ASSERT_PRE_NON_NULL(comp, "Component");
443 BT_ASSERT_PRE_VALID_INDEX(index, comp->input_ports->len);
444 return (void *)
445 borrow_port_by_index(comp->input_ports, index);
72b913fb 446}
366e034f 447
72b913fb 448BT_HIDDEN
d94d92ac
PP
449struct bt_port_output *bt_component_borrow_output_port_by_index(
450 struct bt_component *comp, uint64_t index)
72b913fb 451{
d94d92ac
PP
452 BT_ASSERT_PRE_NON_NULL(comp, "Component");
453 BT_ASSERT_PRE_VALID_INDEX(index, comp->output_ports->len);
454 return (void *)
455 borrow_port_by_index(comp->output_ports, index);
72b913fb 456}
366e034f 457
72b913fb 458BT_HIDDEN
8cc56726 459enum bt_self_component_status bt_component_add_input_port(
3e9b0023 460 struct bt_component *component, const char *name,
8cc56726 461 void *user_data, struct bt_port **port)
72b913fb 462{
d94d92ac 463 /* add_port() logs details */
8cc56726
SM
464 return add_port(component, component->input_ports,
465 BT_PORT_TYPE_INPUT, name, user_data, port);
72b913fb 466}
366e034f 467
72b913fb 468BT_HIDDEN
8cc56726 469enum bt_self_component_status bt_component_add_output_port(
3e9b0023 470 struct bt_component *component, const char *name,
8cc56726 471 void *user_data, struct bt_port **port)
72b913fb 472{
d94d92ac 473 /* add_port() logs details */
8cc56726
SM
474 return add_port(component, component->output_ports,
475 BT_PORT_TYPE_OUTPUT, name, user_data, port);
72b913fb
PP
476}
477
f60c8b34 478BT_HIDDEN
d94d92ac 479enum bt_self_component_status bt_component_accept_port_connection(
8f4799f7
PP
480 struct bt_component *comp, struct bt_port *self_port,
481 struct bt_port *other_port)
f60c8b34 482{
d94d92ac 483 typedef enum bt_self_component_status (*method_t)(
0d72b8c3 484 void *, void *, const void *);
d94d92ac
PP
485
486 enum bt_self_component_status status = BT_SELF_COMPONENT_STATUS_OK;
487 method_t method = NULL;
f60c8b34 488
f6ccaed9
PP
489 BT_ASSERT(comp);
490 BT_ASSERT(self_port);
491 BT_ASSERT(other_port);
72b913fb 492
d94d92ac
PP
493 switch (comp->class->type) {
494 case BT_COMPONENT_CLASS_TYPE_SOURCE:
495 {
496 struct bt_component_class_source *src_cc = (void *) comp->class;
497
498 switch (self_port->type) {
499 case BT_PORT_TYPE_OUTPUT:
500 method = (method_t) src_cc->methods.accept_output_port_connection;
501 break;
502 default:
503 abort();
504 }
505
506 break;
507 }
508 case BT_COMPONENT_CLASS_TYPE_FILTER:
509 {
510 struct bt_component_class_filter *flt_cc = (void *) comp->class;
511
512 switch (self_port->type) {
513 case BT_PORT_TYPE_INPUT:
514 method = (method_t) flt_cc->methods.accept_input_port_connection;
515 break;
516 case BT_PORT_TYPE_OUTPUT:
517 method = (method_t) flt_cc->methods.accept_output_port_connection;
518 break;
519 default:
520 abort();
521 }
522
523 break;
524 }
525 case BT_COMPONENT_CLASS_TYPE_SINK:
526 {
527 struct bt_component_class_sink *sink_cc = (void *) comp->class;
528
529 switch (self_port->type) {
530 case BT_PORT_TYPE_INPUT:
531 method = (method_t) sink_cc->methods.accept_input_port_connection;
532 break;
533 default:
534 abort();
535 }
536
537 break;
538 }
539 default:
540 abort();
541 }
542
543 if (method) {
544 BT_LIB_LOGD("Calling user's \"accept port connection\" method: "
545 "%![comp-]+c, %![self-port-]+p, %![other-port-]+p",
546 comp, self_port, other_port);
0d72b8c3 547 status = method(comp, self_port, (void *) other_port);
ab0d387b 548 BT_LOGD("User method returned: status=%s",
d94d92ac 549 bt_self_component_status_string(status));
f60c8b34
JG
550 }
551
552 return status;
553}
72b913fb 554
0d8b4d8e 555BT_HIDDEN
d94d92ac
PP
556enum bt_self_component_status bt_component_port_connected(
557 struct bt_component *comp, struct bt_port *self_port,
558 struct bt_port *other_port)
0d8b4d8e 559{
d94d92ac 560 typedef enum bt_self_component_status (*method_t)(
0d72b8c3 561 void *, void *, const void *);
d94d92ac
PP
562
563 enum bt_self_component_status status = BT_SELF_COMPONENT_STATUS_OK;
564 method_t method = NULL;
bf55043c 565
f6ccaed9
PP
566 BT_ASSERT(comp);
567 BT_ASSERT(self_port);
568 BT_ASSERT(other_port);
0d8b4d8e 569
d94d92ac
PP
570 switch (comp->class->type) {
571 case BT_COMPONENT_CLASS_TYPE_SOURCE:
572 {
573 struct bt_component_class_source *src_cc = (void *) comp->class;
574
575 switch (self_port->type) {
576 case BT_PORT_TYPE_OUTPUT:
577 method = (method_t) src_cc->methods.output_port_connected;
578 break;
579 default:
580 abort();
581 }
582
583 break;
584 }
585 case BT_COMPONENT_CLASS_TYPE_FILTER:
586 {
587 struct bt_component_class_filter *flt_cc = (void *) comp->class;
588
589 switch (self_port->type) {
590 case BT_PORT_TYPE_INPUT:
591 method = (method_t) flt_cc->methods.input_port_connected;
592 break;
593 case BT_PORT_TYPE_OUTPUT:
594 method = (method_t) flt_cc->methods.output_port_connected;
595 break;
596 default:
597 abort();
598 }
599
600 break;
601 }
602 case BT_COMPONENT_CLASS_TYPE_SINK:
603 {
604 struct bt_component_class_sink *sink_cc = (void *) comp->class;
605
606 switch (self_port->type) {
607 case BT_PORT_TYPE_INPUT:
608 method = (method_t) sink_cc->methods.input_port_connected;
609 break;
610 default:
611 abort();
612 }
613
614 break;
615 }
616 default:
617 abort();
618 }
619
620 if (method) {
621 BT_LIB_LOGD("Calling user's \"port connected\" method: "
622 "%![comp-]+c, %![self-port-]+p, %![other-port-]+p",
623 comp, self_port, other_port);
0d72b8c3 624 status = method(comp, self_port, (void *) other_port);
d94d92ac
PP
625 BT_LOGD("User method returned: status=%s",
626 bt_self_component_status_string(status));
4725a201
PP
627 BT_ASSERT_PRE(status == BT_SELF_COMPONENT_STATUS_OK ||
628 status == BT_SELF_COMPONENT_STATUS_ERROR ||
629 status == BT_SELF_COMPONENT_STATUS_NOMEM,
630 "Unexpected returned component status: status=%s",
631 bt_self_component_status_string(status));
0d8b4d8e 632 }
bf55043c
PP
633
634 return status;
0d8b4d8e
PP
635}
636
3230ee6b
PP
637BT_HIDDEN
638void bt_component_add_destroy_listener(struct bt_component *component,
639 bt_component_destroy_listener_func func, void *data)
640{
641 struct bt_component_destroy_listener listener;
642
f6ccaed9
PP
643 BT_ASSERT(component);
644 BT_ASSERT(func);
3230ee6b
PP
645 listener.func = func;
646 listener.data = data;
647 g_array_append_val(component->destroy_listeners, listener);
3f7d4d90 648 BT_LIB_LOGD("Added destroy listener: %![comp-]+c, "
ab0d387b 649 "func-addr=%p, data-addr=%p",
d94d92ac 650 component, func, data);
3230ee6b
PP
651}
652
653BT_HIDDEN
654void bt_component_remove_destroy_listener(struct bt_component *component,
655 bt_component_destroy_listener_func func, void *data)
656{
d94d92ac 657 uint64_t i;
3230ee6b 658
f6ccaed9
PP
659 BT_ASSERT(component);
660 BT_ASSERT(func);
3230ee6b
PP
661
662 for (i = 0; i < component->destroy_listeners->len; i++) {
663 struct bt_component_destroy_listener *listener =
664 &g_array_index(component->destroy_listeners,
665 struct bt_component_destroy_listener, i);
666
667 if (listener->func == func && listener->data == data) {
668 g_array_remove_index(component->destroy_listeners, i);
669 i--;
3f7d4d90 670 BT_LIB_LOGD("Removed destroy listener: %![comp-]+c, "
ab0d387b 671 "func-addr=%p, data-addr=%p",
d94d92ac 672 component, func, data);
3230ee6b
PP
673 }
674 }
675}
c5b9b441
PP
676
677void bt_component_get_ref(const struct bt_component *component)
678{
679 bt_object_get_ref(component);
680}
681
682void bt_component_put_ref(const struct bt_component *component)
683{
684 bt_object_put_ref(component);
685}
This page took 0.077774 seconds and 4 git commands to generate.