/*
- * component.c
- *
- * Babeltrace Plugin Component
- *
+ * Copyright 2017-2018 Philippe Proulx <pproulx@efficios.com>
* Copyright 2015 Jérémie Galarneau <jeremie.galarneau@efficios.com>
*
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
*/
#define BT_LOG_TAG "COMP"
-#include <babeltrace/lib-logging-internal.h>
-
-#include <babeltrace/graph/private-component.h>
-#include <babeltrace/graph/component.h>
-#include <babeltrace/graph/component-internal.h>
-#include <babeltrace/graph/component-class-internal.h>
-#include <babeltrace/graph/component-source-internal.h>
-#include <babeltrace/graph/component-filter-internal.h>
-#include <babeltrace/graph/component-sink-internal.h>
-#include <babeltrace/graph/private-connection.h>
-#include <babeltrace/graph/connection-internal.h>
-#include <babeltrace/graph/graph-internal.h>
-#include <babeltrace/graph/notification-iterator-internal.h>
-#include <babeltrace/graph/private-connection-private-notification-iterator.h>
-#include <babeltrace/babeltrace-internal.h>
-#include <babeltrace/compiler-internal.h>
-#include <babeltrace/ref.h>
-#include <babeltrace/types.h>
-#include <babeltrace/values.h>
-#include <babeltrace/values-internal.h>
-#include <babeltrace/assert-internal.h>
+#include <babeltrace2/lib-logging-internal.h>
+
+#include <babeltrace2/assert-internal.h>
+#include <babeltrace2/assert-pre-internal.h>
+#include <babeltrace2/graph/self-component.h>
+#include <babeltrace2/graph/component-const.h>
+#include <babeltrace2/graph/component-source-const.h>
+#include <babeltrace2/graph/component-filter-const.h>
+#include <babeltrace2/graph/component-sink-const.h>
+#include <babeltrace2/graph/component-internal.h>
+#include <babeltrace2/graph/component-class-internal.h>
+#include <babeltrace2/graph/component-source-internal.h>
+#include <babeltrace2/graph/component-filter-internal.h>
+#include <babeltrace2/graph/component-sink-internal.h>
+#include <babeltrace2/graph/connection-internal.h>
+#include <babeltrace2/graph/graph-internal.h>
+#include <babeltrace2/graph/message-iterator-internal.h>
+#include <babeltrace2/graph/port-internal.h>
+#include <babeltrace2/babeltrace-internal.h>
+#include <babeltrace2/compiler-internal.h>
+#include <babeltrace2/types.h>
+#include <babeltrace2/value.h>
+#include <babeltrace2/value-internal.h>
#include <stdint.h>
#include <inttypes.h>
static
struct bt_component * (* const component_create_funcs[])(
- struct bt_component_class *) = {
+ const struct bt_component_class *) = {
[BT_COMPONENT_CLASS_TYPE_SOURCE] = bt_component_source_create,
[BT_COMPONENT_CLASS_TYPE_SINK] = bt_component_sink_create,
[BT_COMPONENT_CLASS_TYPE_FILTER] = bt_component_filter_create,
};
static
-void bt_component_destroy(struct bt_object *obj)
+void finalize_component(struct bt_component *comp)
+{
+ typedef void (*method_t)(void *);
+
+ method_t method = NULL;
+
+ BT_ASSERT(comp);
+
+ switch (comp->class->type) {
+ case BT_COMPONENT_CLASS_TYPE_SOURCE:
+ {
+ struct bt_component_class_source *src_cc = (void *) comp->class;
+
+ method = (method_t) src_cc->methods.finalize;
+ break;
+ }
+ case BT_COMPONENT_CLASS_TYPE_FILTER:
+ {
+ struct bt_component_class_filter *flt_cc = (void *) comp->class;
+
+ method = (method_t) flt_cc->methods.finalize;
+ break;
+ }
+ case BT_COMPONENT_CLASS_TYPE_SINK:
+ {
+ struct bt_component_class_sink *sink_cc = (void *) comp->class;
+
+ method = (method_t) sink_cc->methods.finalize;
+ break;
+ }
+ default:
+ abort();
+ }
+
+ if (method) {
+ BT_LIB_LOGD("Calling user's finalization method: "
+ "%![comp-]+c", comp);
+ method(comp);
+ }
+}
+
+static
+void destroy_component(struct bt_object *obj)
{
struct bt_component *component = NULL;
- struct bt_component_class *component_class = NULL;
int i;
if (!obj) {
* The component's reference count is 0 if we're here. Increment
* it to avoid a double-destroy (possibly infinitely recursive).
* This could happen for example if the component's finalization
- * function does bt_get() (or anything that causes bt_get() to
- * be called) on itself (ref. count goes from 0 to 1), and then
- * bt_put(): the reference count would go from 1 to 0 again and
- * this function would be called again.
+ * function does bt_object_get_ref() (or anything that causes
+ * bt_object_get_ref() to be called) on itself (ref. count goes
+ * from 0 to 1), and then bt_object_put_ref(): the reference
+ * count would go from 1 to 0 again and this function would be
+ * called again.
*/
- obj->ref_count.count++;
+ obj->ref_count++;
component = container_of(obj, struct bt_component, base);
- BT_LOGD("Destroying component: addr=%p, name=\"%s\", graph-addr=%p",
- component, bt_component_get_name(component),
- obj->parent);
+ BT_LIB_LOGD("Destroying component: %![comp-]+c, %![graph-]+g",
+ component, bt_component_borrow_graph(component));
/* Call destroy listeners in reverse registration order */
BT_LOGD_STR("Calling destroy listeners.");
listener->func(component, listener->data);
}
- component_class = component->class;
-
/*
* User data is destroyed first, followed by the concrete
* component instance. Do not finalize if the component's user
* initialization method failed in the first place.
*/
- if (component->initialized && component->class->methods.finalize) {
- BT_LOGD_STR("Calling user's finalization method.");
- component->class->methods.finalize(
- bt_private_component_from_component(component));
+ if (component->initialized) {
+ finalize_component(component);
}
if (component->destroy) {
if (component->input_ports) {
BT_LOGD_STR("Destroying input ports.");
g_ptr_array_free(component->input_ports, TRUE);
+ component->input_ports = NULL;
}
if (component->output_ports) {
BT_LOGD_STR("Destroying output ports.");
g_ptr_array_free(component->output_ports, TRUE);
+ component->output_ports = NULL;
}
if (component->destroy_listeners) {
g_array_free(component->destroy_listeners, TRUE);
+ component->destroy_listeners = NULL;
}
if (component->name) {
g_string_free(component->name, TRUE);
+ component->name = NULL;
}
- BT_LOGD("Putting component class.");
- bt_put(component_class);
+ BT_LOGD_STR("Putting component class.");
+ BT_OBJECT_PUT_REF_AND_RESET(component->class);
g_free(component);
}
-struct bt_component *bt_component_from_private(
- struct bt_private_component *private_component)
-{
- return bt_get(bt_component_borrow_from_private(private_component));
-}
-
enum bt_component_class_type bt_component_get_class_type(
- struct bt_component *component)
+ const struct bt_component *component)
{
- return component ? component->class->type : BT_COMPONENT_CLASS_TYPE_UNKNOWN;
+ BT_ASSERT_PRE_NON_NULL(component, "Component");
+ return component->class->type;
}
static
-struct bt_port *bt_component_add_port(
+enum bt_self_component_status add_port(
struct bt_component *component, GPtrArray *ports,
- enum bt_port_type port_type, const char *name, void *user_data)
+ enum bt_port_type port_type, const char *name, void *user_data,
+ struct bt_port **port)
{
- size_t i;
struct bt_port *new_port = NULL;
struct bt_graph *graph = NULL;
-
- if (!name) {
- BT_LOGW_STR("Invalid parameter: name is NULL.");
- goto end;
- }
-
- if (strlen(name) == 0) {
- BT_LOGW_STR("Invalid parameter: name is an empty string.");
- goto end;
- }
-
- BT_LOGD("Adding port to component: comp-addr=%p, comp-name=\"%s\", "
+ enum bt_self_component_status status;
+
+ BT_ASSERT_PRE_NON_NULL(component, "Component");
+ BT_ASSERT_PRE_NON_NULL(name, "Name");
+ BT_ASSERT_PRE(strlen(name) > 0, "Name is empty");
+ graph = bt_component_borrow_graph(component);
+ BT_ASSERT_PRE(graph && !bt_graph_is_canceled(graph),
+ "Component's graph is canceled: %![comp-]+c, %![graph-]+g",
+ component, graph);
+ BT_ASSERT_PRE(
+ graph->config_state == BT_GRAPH_CONFIGURATION_STATE_CONFIGURING,
+ "Component's graph is already configured: "
+ "%![comp-]+c, %![graph-]+g", component, graph);
+
+ // TODO: Validate that the name is not already used.
+
+ BT_LIB_LOGD("Adding port to component: %![comp-]+c, "
"port-type=%s, port-name=\"%s\"", component,
- bt_component_get_name(component),
bt_port_type_string(port_type), name);
- /* Look for a port having the same name. */
- for (i = 0; i < ports->len; i++) {
- const char *port_name;
- struct bt_port *port = g_ptr_array_index(ports, i);
-
- port_name = bt_port_get_name(port);
- BT_ASSERT(port_name);
-
- if (!strcmp(name, port_name)) {
- /* Port name clash, abort. */
- BT_LOGW("Invalid parameter: another port with the same name already exists in the component: "
- "other-port-addr=%p", port);
- goto end;
- }
- }
-
new_port = bt_port_create(component, port_type, name, user_data);
if (!new_port) {
- BT_LOGE("Cannot create port object.");
- goto end;
+ BT_LOGE_STR("Cannot create port object.");
+ status = BT_SELF_COMPONENT_STATUS_NOMEM;
+ goto error;
}
/*
/*
* Notify the graph's creator that a new port was added.
*/
- graph = bt_component_get_graph(component);
+ graph = bt_component_borrow_graph(component);
if (graph) {
- bt_graph_notify_port_added(graph, new_port);
- BT_PUT(graph);
+ enum bt_graph_listener_status listener_status;
+
+ listener_status = bt_graph_notify_port_added(graph, new_port);
+ if (listener_status != BT_GRAPH_LISTENER_STATUS_OK) {
+ bt_graph_make_faulty(graph);
+ status = listener_status;
+ goto error;
+ }
}
- BT_LOGD("Created and added port to component: comp-addr=%p, comp-name=\"%s\", "
- "port-type=%s, port-name=\"%s\", port-addr=%p", component,
- bt_component_get_name(component),
- bt_port_type_string(port_type), name, new_port);
+ BT_LIB_LOGD("Created and added port to component: "
+ "%![comp-]+c, %![port-]+p", component, new_port);
+
+ *port = new_port;
+ status = BT_SELF_COMPONENT_STATUS_OK;
+
+ goto end;
+error:
+ /*
+ * We need to release the reference that we would otherwise have
+ * returned to the caller.
+ */
+ BT_PORT_PUT_REF_AND_RESET(new_port);
end:
- return new_port;
+ return status;
}
BT_HIDDEN
-int64_t bt_component_get_input_port_count(struct bt_component *comp)
+uint64_t bt_component_get_input_port_count(const struct bt_component *comp)
{
- BT_ASSERT(comp);
- return (int64_t) comp->input_ports->len;
+ BT_ASSERT_PRE_NON_NULL(comp, "Component");
+ return (uint64_t) comp->input_ports->len;
}
BT_HIDDEN
-int64_t bt_component_get_output_port_count(struct bt_component *comp)
+uint64_t bt_component_get_output_port_count(const struct bt_component *comp)
{
- BT_ASSERT(comp);
- return (int64_t) comp->output_ports->len;
+ BT_ASSERT_PRE_NON_NULL(comp, "Component");
+ return (uint64_t) comp->output_ports->len;
}
BT_HIDDEN
-enum bt_component_status bt_component_create(
- struct bt_component_class *component_class,
+int bt_component_create(struct bt_component_class *component_class,
const char *name, struct bt_component **user_component)
{
- enum bt_component_status status = BT_COMPONENT_STATUS_OK;
+ int ret = 0;
struct bt_component *component = NULL;
enum bt_component_class_type type;
BT_ASSERT(user_component);
BT_ASSERT(component_class);
BT_ASSERT(name);
-
type = bt_component_class_get_type(component_class);
- BT_LOGD("Creating empty component from component class: "
- "comp-cls-addr=%p, comp-cls-type=%s, name=\"%s\"",
- component_class, bt_component_class_type_string(type), name);
+ BT_LIB_LOGD("Creating empty component from component class: %![cc-]+C, "
+ "comp-name=\"%s\"", component_class, name);
component = component_create_funcs[type](component_class);
if (!component) {
BT_LOGE_STR("Cannot create specific component object.");
- status = BT_COMPONENT_STATUS_NOMEM;
+ ret = -1;
goto end;
}
- bt_object_init(component, bt_component_destroy);
- component->class = bt_get(component_class);
+ bt_object_init_shared_with_parent(&component->base, destroy_component);
+ component->class = component_class;
+ bt_object_get_no_null_check(component->class);
component->destroy = component_destroy_funcs[type];
component->name = g_string_new(name);
if (!component->name) {
BT_LOGE_STR("Failed to allocate one GString.");
- status = BT_COMPONENT_STATUS_NOMEM;
+ ret = -1;
goto end;
}
component->input_ports = g_ptr_array_new_with_free_func(
- bt_object_release);
+ (GDestroyNotify) bt_object_try_spec_release);
if (!component->input_ports) {
BT_LOGE_STR("Failed to allocate one GPtrArray.");
- status = BT_COMPONENT_STATUS_NOMEM;
+ ret = -1;
goto end;
}
component->output_ports = g_ptr_array_new_with_free_func(
- bt_object_release);
+ (GDestroyNotify) bt_object_try_spec_release);
if (!component->output_ports) {
BT_LOGE_STR("Failed to allocate one GPtrArray.");
- status = BT_COMPONENT_STATUS_NOMEM;
+ ret = -1;
goto end;
}
sizeof(struct bt_component_destroy_listener));
if (!component->destroy_listeners) {
BT_LOGE_STR("Failed to allocate one GArray.");
- status = BT_COMPONENT_STATUS_NOMEM;
+ ret = -1;
goto end;
}
- BT_LOGD("Created empty component from component class: "
- "comp-cls-addr=%p, comp-cls-type=%s, name=\"%s\", comp-addr=%p",
- component_class, bt_component_class_type_string(type), name,
- component);
- BT_MOVE(*user_component, component);
+ BT_LIB_LOGD("Created empty component from component class: "
+ "%![cc-]+C, %![comp-]+c", component_class, component);
+ BT_OBJECT_MOVE_REF(*user_component, component);
end:
- bt_put(component);
- return status;
+ bt_object_put_ref(component);
+ return ret;
}
-const char *bt_component_get_name(struct bt_component *component)
+const char *bt_component_get_name(const struct bt_component *component)
{
- const char *ret = NULL;
-
- if (!component) {
- BT_LOGW_STR("Invalid parameter: component is NULL.");
- goto end;
- }
-
- ret = component->name->len == 0 ? NULL : component->name->str;
-
-end:
- return ret;
+ BT_ASSERT_PRE_NON_NULL(component, "Component");
+ return component->name->str;
}
-struct bt_component_class *bt_component_get_class(
- struct bt_component *component)
+const struct bt_component_class *bt_component_borrow_class_const(
+ const struct bt_component *component)
{
- return component ? bt_get(component->class) : NULL;
+ BT_ASSERT_PRE_NON_NULL(component, "Component");
+ return component->class;
}
-void *bt_private_component_get_user_data(
- struct bt_private_component *private_component)
+void *bt_self_component_get_data(const struct bt_self_component *self_comp)
{
- struct bt_component *component =
- bt_component_borrow_from_private(private_component);
+ struct bt_component *component = (void *) self_comp;
- return component ? component->user_data : NULL;
+ BT_ASSERT_PRE_NON_NULL(component, "Component");
+ return component->user_data;
}
-enum bt_component_status bt_private_component_set_user_data(
- struct bt_private_component *private_component,
+void bt_self_component_set_data(struct bt_self_component *self_comp,
void *data)
{
- struct bt_component *component =
- bt_component_borrow_from_private(private_component);
- enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
-
- if (!component) {
- BT_LOGW_STR("Invalid parameter: component is NULL.");
- ret = BT_COMPONENT_STATUS_INVALID;
- goto end;
- }
+ struct bt_component *component = (void *) self_comp;
+ BT_ASSERT_PRE_NON_NULL(component, "Component");
component->user_data = data;
- BT_LOGV("Set component's user data: "
- "comp-addr=%p, comp-name=\"%s\", user-data-addr=%p",
- component, bt_component_get_name(component), data);
-
-end:
- return ret;
+ BT_LIB_LOGV("Set component's user data: %!+c", component);
}
BT_HIDDEN
void bt_component_set_graph(struct bt_component *component,
struct bt_graph *graph)
{
- bt_object_set_parent(component, graph ? &graph->base : NULL);
+ bt_object_set_parent(&component->base,
+ graph ? &graph->base : NULL);
}
-struct bt_graph *bt_component_get_graph(
- struct bt_component *component)
+bt_bool bt_component_graph_is_canceled(const struct bt_component *component)
{
- return (struct bt_graph *) bt_object_get_parent(&component->base);
+ return bt_graph_is_canceled(
+ (void *) bt_object_borrow_parent(&component->base));
}
static
-struct bt_port *bt_component_get_port_by_name(GPtrArray *ports,
+struct bt_port *borrow_port_by_name(GPtrArray *ports,
const char *name)
{
- size_t i;
+ uint64_t i;
struct bt_port *ret_port = NULL;
BT_ASSERT(name);
for (i = 0; i < ports->len; i++) {
struct bt_port *port = g_ptr_array_index(ports, i);
- const char *port_name = bt_port_get_name(port);
-
- if (!port_name) {
- continue;
- }
- if (!strcmp(name, port_name)) {
- ret_port = bt_get(port);
+ if (!strcmp(name, port->name->str)) {
+ ret_port = port;
break;
}
}
}
BT_HIDDEN
-struct bt_port *bt_component_get_input_port_by_name(struct bt_component *comp,
- const char *name)
+struct bt_port_input *bt_component_borrow_input_port_by_name(
+ struct bt_component *comp, const char *name)
{
BT_ASSERT(comp);
-
- return bt_component_get_port_by_name(comp->input_ports, name);
+ return (void *) borrow_port_by_name(comp->input_ports, name);
}
BT_HIDDEN
-struct bt_port *bt_component_get_output_port_by_name(struct bt_component *comp,
- const char *name)
+struct bt_port_output *bt_component_borrow_output_port_by_name(
+ struct bt_component *comp, const char *name)
{
- BT_ASSERT(comp);
-
- return bt_component_get_port_by_name(comp->output_ports, name);
+ BT_ASSERT_PRE_NON_NULL(comp, "Component");
+ return (void *)
+ borrow_port_by_name(comp->output_ports, name);
}
static
-struct bt_port *bt_component_get_port_by_index(GPtrArray *ports, uint64_t index)
+struct bt_port *borrow_port_by_index(GPtrArray *ports, uint64_t index)
{
- struct bt_port *port = NULL;
-
- if (index >= ports->len) {
- BT_LOGW("Invalid parameter: index is out of bounds: "
- "index=%" PRIu64 ", count=%u",
- index, ports->len);
- goto end;
- }
-
- port = bt_get(g_ptr_array_index(ports, index));
-end:
- return port;
+ BT_ASSERT(index < ports->len);
+ return g_ptr_array_index(ports, index);
}
BT_HIDDEN
-struct bt_port *bt_component_get_input_port_by_index(struct bt_component *comp,
- uint64_t index)
+struct bt_port_input *bt_component_borrow_input_port_by_index(
+ struct bt_component *comp, uint64_t index)
{
- BT_ASSERT(comp);
-
- return bt_component_get_port_by_index(comp->input_ports, index);
+ BT_ASSERT_PRE_NON_NULL(comp, "Component");
+ BT_ASSERT_PRE_VALID_INDEX(index, comp->input_ports->len);
+ return (void *)
+ borrow_port_by_index(comp->input_ports, index);
}
BT_HIDDEN
-struct bt_port *bt_component_get_output_port_by_index(struct bt_component *comp,
- uint64_t index)
+struct bt_port_output *bt_component_borrow_output_port_by_index(
+ struct bt_component *comp, uint64_t index)
{
- BT_ASSERT(comp);
-
- return bt_component_get_port_by_index(comp->output_ports, index);
+ BT_ASSERT_PRE_NON_NULL(comp, "Component");
+ BT_ASSERT_PRE_VALID_INDEX(index, comp->output_ports->len);
+ return (void *)
+ borrow_port_by_index(comp->output_ports, index);
}
BT_HIDDEN
-struct bt_port *bt_component_add_input_port(
+enum bt_self_component_status bt_component_add_input_port(
struct bt_component *component, const char *name,
- void *user_data)
+ void *user_data, struct bt_port **port)
{
- /* bt_component_add_port() logs details */
- return bt_component_add_port(component, component->input_ports,
- BT_PORT_TYPE_INPUT, name, user_data);
+ /* add_port() logs details */
+ return add_port(component, component->input_ports,
+ BT_PORT_TYPE_INPUT, name, user_data, port);
}
BT_HIDDEN
-struct bt_port *bt_component_add_output_port(
+enum bt_self_component_status bt_component_add_output_port(
struct bt_component *component, const char *name,
- void *user_data)
+ void *user_data, struct bt_port **port)
{
- /* bt_component_add_port() logs details */
- return bt_component_add_port(component, component->output_ports,
- BT_PORT_TYPE_OUTPUT, name, user_data);
+ /* add_port() logs details */
+ return add_port(component, component->output_ports,
+ BT_PORT_TYPE_OUTPUT, name, user_data, port);
}
-static
-void bt_component_remove_port_by_index(struct bt_component *component,
- GPtrArray *ports, size_t index)
+BT_HIDDEN
+enum bt_self_component_status bt_component_accept_port_connection(
+ struct bt_component *comp, struct bt_port *self_port,
+ struct bt_port *other_port)
{
- struct bt_port *port;
- struct bt_graph *graph;
+ typedef enum bt_self_component_status (*method_t)(
+ void *, void *, const void *);
- BT_ASSERT(ports);
- BT_ASSERT(index < ports->len);
- port = g_ptr_array_index(ports, index);
-
- BT_LOGD("Removing port from component: "
- "comp-addr=%p, comp-name=\"%s\", "
- "port-addr=%p, port-name=\"%s\"",
- component, bt_component_get_name(component),
- port, bt_port_get_name(port));
+ enum bt_self_component_status status = BT_SELF_COMPONENT_STATUS_OK;
+ method_t method = NULL;
- /* Disconnect both ports of this port's connection, if any */
- if (port->connection) {
- bt_connection_end(port->connection, true);
- }
+ BT_ASSERT(comp);
+ BT_ASSERT(self_port);
+ BT_ASSERT(other_port);
- /* Remove from parent's array of ports (weak refs) */
- g_ptr_array_remove_index(ports, index);
+ switch (comp->class->type) {
+ case BT_COMPONENT_CLASS_TYPE_SOURCE:
+ {
+ struct bt_component_class_source *src_cc = (void *) comp->class;
- /* Detach port from its component parent */
- BT_PUT(port->base.parent);
+ switch (self_port->type) {
+ case BT_PORT_TYPE_OUTPUT:
+ method = (method_t) src_cc->methods.accept_output_port_connection;
+ break;
+ default:
+ abort();
+ }
- /*
- * Notify the graph's creator that a port is removed.
- */
- graph = bt_component_get_graph(component);
- if (graph) {
- bt_graph_notify_port_removed(graph, component, port);
- BT_PUT(graph);
+ break;
}
+ case BT_COMPONENT_CLASS_TYPE_FILTER:
+ {
+ struct bt_component_class_filter *flt_cc = (void *) comp->class;
- BT_LOGD("Removed port from component: "
- "comp-addr=%p, comp-name=\"%s\", "
- "port-addr=%p, port-name=\"%s\"",
- component, bt_component_get_name(component),
- port, bt_port_get_name(port));
-}
-
-BT_HIDDEN
-enum bt_component_status bt_component_remove_port(
- struct bt_component *component, struct bt_port *port)
-{
- size_t i;
- enum bt_component_status status = BT_COMPONENT_STATUS_OK;
- GPtrArray *ports = NULL;
+ switch (self_port->type) {
+ case BT_PORT_TYPE_INPUT:
+ method = (method_t) flt_cc->methods.accept_input_port_connection;
+ break;
+ case BT_PORT_TYPE_OUTPUT:
+ method = (method_t) flt_cc->methods.accept_output_port_connection;
+ break;
+ default:
+ abort();
+ }
- if (!component) {
- BT_LOGW_STR("Invalid parameter: component is NULL.");
- status = BT_COMPONENT_STATUS_INVALID;
- goto end;
+ break;
}
+ case BT_COMPONENT_CLASS_TYPE_SINK:
+ {
+ struct bt_component_class_sink *sink_cc = (void *) comp->class;
- if (!port) {
- BT_LOGW_STR("Invalid parameter: port is NULL.");
- status = BT_COMPONENT_STATUS_INVALID;
- goto end;
- }
+ switch (self_port->type) {
+ case BT_PORT_TYPE_INPUT:
+ method = (method_t) sink_cc->methods.accept_input_port_connection;
+ break;
+ default:
+ abort();
+ }
- if (bt_port_get_type(port) == BT_PORT_TYPE_INPUT) {
- ports = component->input_ports;
- } else if (bt_port_get_type(port) == BT_PORT_TYPE_OUTPUT) {
- ports = component->output_ports;
+ break;
}
-
- BT_ASSERT(ports);
-
- for (i = 0; i < ports->len; i++) {
- struct bt_port *cur_port = g_ptr_array_index(ports, i);
-
- if (cur_port == port) {
- bt_component_remove_port_by_index(component,
- ports, i);
- goto end;
- }
+ default:
+ abort();
}
- status = BT_COMPONENT_STATUS_NOT_FOUND;
- BT_LOGW("Port to remove from component was not found: "
- "comp-addr=%p, comp-name=\"%s\", "
- "port-addr=%p, port-name=\"%s\"",
- component, bt_component_get_name(component),
- port, bt_port_get_name(port));
+ if (method) {
+ BT_LIB_LOGD("Calling user's \"accept port connection\" method: "
+ "%![comp-]+c, %![self-port-]+p, %![other-port-]+p",
+ comp, self_port, other_port);
+ status = method(comp, self_port, (void *) other_port);
+ BT_LOGD("User method returned: status=%s",
+ bt_self_component_status_string(status));
+ }
-end:
return status;
}
BT_HIDDEN
-enum bt_component_status bt_component_accept_port_connection(
+enum bt_self_component_status bt_component_port_connected(
struct bt_component *comp, struct bt_port *self_port,
struct bt_port *other_port)
{
- enum bt_component_status status = BT_COMPONENT_STATUS_OK;
+ typedef enum bt_self_component_status (*method_t)(
+ void *, void *, const void *);
+
+ enum bt_self_component_status status = BT_SELF_COMPONENT_STATUS_OK;
+ method_t method = NULL;
BT_ASSERT(comp);
BT_ASSERT(self_port);
BT_ASSERT(other_port);
- if (comp->class->methods.accept_port_connection) {
- BT_LOGD("Calling user's \"accept port connection\" method: "
- "comp-addr=%p, comp-name=\"%s\", "
- "self-port-addr=%p, self-port-name=\"%s\", "
- "other-port-addr=%p, other-port-name=\"%s\"",
- comp, bt_component_get_name(comp),
- self_port, bt_port_get_name(self_port),
- other_port, bt_port_get_name(other_port));
- status = comp->class->methods.accept_port_connection(
- bt_private_component_from_component(comp),
- bt_private_port_from_port(self_port),
- other_port);
- BT_LOGD("User method returned: status=%s",
- bt_component_status_string(status));
+ switch (comp->class->type) {
+ case BT_COMPONENT_CLASS_TYPE_SOURCE:
+ {
+ struct bt_component_class_source *src_cc = (void *) comp->class;
+
+ switch (self_port->type) {
+ case BT_PORT_TYPE_OUTPUT:
+ method = (method_t) src_cc->methods.output_port_connected;
+ break;
+ default:
+ abort();
+ }
+
+ break;
}
+ case BT_COMPONENT_CLASS_TYPE_FILTER:
+ {
+ struct bt_component_class_filter *flt_cc = (void *) comp->class;
- return status;
-}
+ switch (self_port->type) {
+ case BT_PORT_TYPE_INPUT:
+ method = (method_t) flt_cc->methods.input_port_connected;
+ break;
+ case BT_PORT_TYPE_OUTPUT:
+ method = (method_t) flt_cc->methods.output_port_connected;
+ break;
+ default:
+ abort();
+ }
-BT_HIDDEN
-void bt_component_port_connected(struct bt_component *comp,
- struct bt_port *self_port, struct bt_port *other_port)
-{
- BT_ASSERT(comp);
- BT_ASSERT(self_port);
- BT_ASSERT(other_port);
+ break;
+ }
+ case BT_COMPONENT_CLASS_TYPE_SINK:
+ {
+ struct bt_component_class_sink *sink_cc = (void *) comp->class;
+
+ switch (self_port->type) {
+ case BT_PORT_TYPE_INPUT:
+ method = (method_t) sink_cc->methods.input_port_connected;
+ break;
+ default:
+ abort();
+ }
- if (comp->class->methods.port_connected) {
- BT_LOGD("Calling user's \"port connected\" method: "
- "comp-addr=%p, comp-name=\"%s\", "
- "self-port-addr=%p, self-port-name=\"%s\", "
- "other-port-addr=%p, other-port-name=\"%s\"",
- comp, bt_component_get_name(comp),
- self_port, bt_port_get_name(self_port),
- other_port, bt_port_get_name(other_port));
- comp->class->methods.port_connected(
- bt_private_component_from_component(comp),
- bt_private_port_from_port(self_port), other_port);
+ break;
+ }
+ default:
+ abort();
}
-}
-BT_HIDDEN
-void bt_component_port_disconnected(struct bt_component *comp,
- struct bt_port *port)
-{
- BT_ASSERT(comp);
- BT_ASSERT(port);
-
- if (comp->class->methods.port_disconnected) {
- BT_LOGD("Calling user's \"port disconnected\" method: "
- "comp-addr=%p, comp-name=\"%s\", "
- "port-addr=%p, port-name=\"%s\"",
- comp, bt_component_get_name(comp),
- port, bt_port_get_name(port));
- comp->class->methods.port_disconnected(
- bt_private_component_from_component(comp),
- bt_private_port_from_port(port));
+ if (method) {
+ BT_LIB_LOGD("Calling user's \"port connected\" method: "
+ "%![comp-]+c, %![self-port-]+p, %![other-port-]+p",
+ comp, self_port, other_port);
+ status = method(comp, self_port, (void *) other_port);
+ BT_LOGD("User method returned: status=%s",
+ bt_self_component_status_string(status));
+ BT_ASSERT_PRE(status == BT_SELF_COMPONENT_STATUS_OK ||
+ status == BT_SELF_COMPONENT_STATUS_ERROR ||
+ status == BT_SELF_COMPONENT_STATUS_NOMEM,
+ "Unexpected returned component status: status=%s",
+ bt_self_component_status_string(status));
}
+
+ return status;
}
BT_HIDDEN
listener.func = func;
listener.data = data;
g_array_append_val(component->destroy_listeners, listener);
- BT_LOGV("Added destroy listener: "
- "comp-addr=%p, comp-name=\"%s\", "
+ BT_LIB_LOGV("Added destroy listener: %![comp-]+c, "
"func-addr=%p, data-addr=%p",
- component, bt_component_get_name(component),
- func, data);
+ component, func, data);
}
BT_HIDDEN
void bt_component_remove_destroy_listener(struct bt_component *component,
bt_component_destroy_listener_func func, void *data)
{
- size_t i;
+ uint64_t i;
BT_ASSERT(component);
BT_ASSERT(func);
if (listener->func == func && listener->data == data) {
g_array_remove_index(component->destroy_listeners, i);
i--;
- BT_LOGV("Removed destroy listener: "
- "comp-addr=%p, comp-name=\"%s\", "
+ BT_LIB_LOGV("Removed destroy listener: %![comp-]+c, "
"func-addr=%p, data-addr=%p",
- component, bt_component_get_name(component),
- func, data);
+ component, func, data);
}
}
}
+
+void bt_component_get_ref(const struct bt_component *component)
+{
+ bt_object_get_ref(component);
+}
+
+void bt_component_put_ref(const struct bt_component *component)
+{
+ bt_object_put_ref(component);
+}