* SOFTWARE.
*/
-#include <babeltrace/component/component.h>
-#include <babeltrace/component/component-internal.h>
-#include <babeltrace/component/component-class-internal.h>
-#include <babeltrace/component/component-source-internal.h>
-#include <babeltrace/component/component-filter-internal.h>
-#include <babeltrace/component/component-sink-internal.h>
-#include <babeltrace/component/graph-internal.h>
-#include <babeltrace/component/notification/iterator-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-notification-iterator.h>
#include <babeltrace/babeltrace-internal.h>
-#include <babeltrace/compiler.h>
+#include <babeltrace/compiler-internal.h>
#include <babeltrace/ref.h>
static
[BT_COMPONENT_CLASS_TYPE_FILTER] = bt_component_filter_create,
};
+static
+void (*component_destroy_funcs[])(struct bt_component *) = {
+ [BT_COMPONENT_CLASS_TYPE_SOURCE] = bt_component_source_destroy,
+ [BT_COMPONENT_CLASS_TYPE_SINK] = bt_component_sink_destroy,
+ [BT_COMPONENT_CLASS_TYPE_FILTER] = bt_component_filter_destroy,
+};
+
static
enum bt_component_status (* const component_validation_funcs[])(
struct bt_component *) = {
* User data is destroyed first, followed by the concrete component
* instance.
*/
- if (component->class->methods.destroy) {
- component->class->methods.destroy(component);
+ if (component->class->methods.finalize) {
+ component->class->methods.finalize(
+ bt_private_component_from_component(component));
}
if (component->destroy) {
component->destroy(component);
}
+ if (component->input_ports) {
+ g_ptr_array_free(component->input_ports, TRUE);
+ }
+
+ if (component->output_ports) {
+ g_ptr_array_free(component->output_ports, TRUE);
+ }
+
g_string_free(component->name, TRUE);
bt_put(component_class);
g_free(component);
}
-BT_HIDDEN
-enum bt_component_status bt_component_init(struct bt_component *component,
- bt_component_class_destroy_method destroy)
+struct bt_component *bt_component_from_private_component(
+ struct bt_private_component *private_component)
{
- enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
-
- if (!component) {
- ret = BT_COMPONENT_STATUS_INVALID;
- goto end;
- }
-
- component->initializing = true;
- component->destroy = destroy;
-end:
- return ret;
+ return bt_get(bt_component_from_private(private_component));
}
enum bt_component_class_type bt_component_get_class_type(
return component ? component->class->type : BT_COMPONENT_CLASS_TYPE_UNKNOWN;
}
-BT_HIDDEN
-struct bt_notification_iterator *bt_component_create_iterator(
- struct bt_component *component, void *init_method_data)
+static
+struct bt_port *bt_component_add_port(
+ struct bt_component *component, GPtrArray *ports,
+ enum bt_port_type port_type, const char *name)
{
- enum bt_notification_iterator_status ret_iterator;
- enum bt_component_class_type type;
- struct bt_notification_iterator *iterator = NULL;
- struct bt_component_class *class = component->class;
-
- if (!component) {
- goto error;
- }
-
- type = bt_component_get_class_type(component);
- if (type != BT_COMPONENT_CLASS_TYPE_SOURCE &&
- type != BT_COMPONENT_CLASS_TYPE_FILTER) {
- /* Unsupported operation. */
- goto error;
- }
+ size_t i;
+ struct bt_port *new_port = NULL;
+ struct bt_graph *graph = NULL;
- iterator = bt_notification_iterator_create(component);
- if (!iterator) {
- goto error;
+ if (!name || strlen(name) == 0) {
+ goto end;
}
- switch (type) {
- case BT_COMPONENT_CLASS_TYPE_SOURCE:
- {
- struct bt_component_class_source *source_class;
- enum bt_notification_iterator_status status;
-
- source_class = container_of(class, struct bt_component_class_source, parent);
+ /* 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);
- if (source_class->methods.iterator.init) {
- status = source_class->methods.iterator.init(component,
- iterator, init_method_data);
- if (status < 0) {
- goto error;
- }
+ port_name = bt_port_get_name(port);
+ if (!port_name) {
+ continue;
}
- break;
- }
- case BT_COMPONENT_CLASS_TYPE_FILTER:
- {
- struct bt_component_class_filter *filter_class;
- enum bt_notification_iterator_status status;
-
- filter_class = container_of(class, struct bt_component_class_filter, parent);
- if (filter_class->methods.iterator.init) {
- status = filter_class->methods.iterator.init(component,
- iterator, init_method_data);
- if (status < 0) {
- goto error;
- }
+ if (!strcmp(name, port_name)) {
+ /* Port name clash, abort. */
+ goto end;
}
- break;
}
- default:
- /* Unreachable. */
- assert(0);
+
+ new_port = bt_port_create(component, port_type, name);
+ if (!new_port) {
+ goto end;
}
- ret_iterator = bt_notification_iterator_validate(iterator);
- if (ret_iterator != BT_NOTIFICATION_ITERATOR_STATUS_OK) {
- goto error;
+ /*
+ * No name clash, add the port.
+ * The component is now the port's parent; it should _not_
+ * hold a reference to the port since the port's lifetime
+ * is now protected by the component's own lifetime.
+ */
+ g_ptr_array_add(ports, new_port);
+
+ /*
+ * Notify the graph's creator that a new port was added.
+ */
+ graph = bt_component_get_graph(component);
+ if (graph) {
+ bt_graph_notify_port_added(graph, new_port);
+ BT_PUT(graph);
}
- return iterator;
-error:
- BT_PUT(iterator);
- return iterator;
+end:
+ return new_port;
+}
+
+BT_HIDDEN
+uint64_t bt_component_get_input_port_count(struct bt_component *comp)
+{
+ assert(comp);
+ return comp->input_ports->len;
+}
+
+BT_HIDDEN
+uint64_t bt_component_get_output_port_count(struct bt_component *comp)
+{
+ assert(comp);
+ return comp->output_ports->len;
}
struct bt_component *bt_component_create_with_init_method_data(
int ret;
struct bt_component *component = NULL;
enum bt_component_class_type type;
+ struct bt_port *default_port = NULL;
if (!component_class) {
goto end;
}
bt_object_init(component, bt_component_destroy);
+ component->class = bt_get(component_class);
+ component->destroy = component_destroy_funcs[type];
component->name = g_string_new(name);
if (!component->name) {
BT_PUT(component);
goto end;
}
+ component->input_ports = g_ptr_array_new_with_free_func(
+ bt_object_release);
+ if (!component->input_ports) {
+ BT_PUT(component);
+ goto end;
+ }
+
+ component->output_ports = g_ptr_array_new_with_free_func(
+ bt_object_release);
+ if (!component->output_ports) {
+ BT_PUT(component);
+ goto end;
+ }
+
+ if (type == BT_COMPONENT_CLASS_TYPE_SOURCE ||
+ type == BT_COMPONENT_CLASS_TYPE_FILTER) {
+ default_port = bt_component_add_port(component,
+ component->output_ports, BT_PORT_TYPE_OUTPUT,
+ DEFAULT_OUTPUT_PORT_NAME);
+ if (!default_port) {
+ BT_PUT(component);
+ goto end;
+ }
+
+ BT_PUT(default_port);
+ }
+
+ if (type == BT_COMPONENT_CLASS_TYPE_FILTER ||
+ type == BT_COMPONENT_CLASS_TYPE_SINK) {
+ default_port = bt_component_add_port(component,
+ component->input_ports, BT_PORT_TYPE_INPUT,
+ DEFAULT_INPUT_PORT_NAME);
+ if (!default_port) {
+ BT_PUT(component);
+ goto end;
+ }
+
+ BT_PUT(default_port);
+ }
+
+ component->initializing = true;
+
if (component_class->methods.init) {
- ret = component_class->methods.init(component, params,
+ ret = component_class->methods.init(
+ bt_private_component_from_component(component), params,
init_method_data);
component->initializing = false;
if (ret != BT_COMPONENT_STATUS_OK) {
bt_component_class_freeze(component->class);
end:
+ bt_put(default_port);
return component;
}
return component ? bt_get(component->class) : NULL;
}
-void *bt_component_get_private_data(struct bt_component *component)
+void *bt_private_component_get_user_data(
+ struct bt_private_component *private_component)
{
+ struct bt_component *component =
+ bt_component_from_private(private_component);
+
return component ? component->user_data : NULL;
}
-enum bt_component_status
-bt_component_set_private_data(struct bt_component *component,
+enum bt_component_status bt_private_component_set_user_data(
+ struct bt_private_component *private_component,
void *data)
{
+ struct bt_component *component =
+ bt_component_from_private(private_component);
enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
if (!component || !component->initializing) {
return (struct bt_graph *) bt_object_get_parent(&component->base);
}
-BT_HIDDEN
-int bt_component_init_input_ports(struct bt_component *component,
- GPtrArray **input_ports)
-{
- int ret = 0;
- struct bt_port *default_port;
-
- *input_ports = g_ptr_array_new_with_free_func(bt_object_release);
- if (!*input_ports) {
- ret = -1;
- goto end;
- }
-
- default_port = bt_component_add_port(component, *input_ports,
- BT_PORT_TYPE_INPUT, DEFAULT_INPUT_PORT_NAME);
- if (!default_port) {
- ret = -1;
- goto end;
- }
- bt_put(default_port);
-end:
- return ret;
-}
-
-BT_HIDDEN
-int bt_component_init_output_ports(struct bt_component *component,
- GPtrArray **output_ports)
-{
- int ret = 0;
- struct bt_port *default_port;
-
- *output_ports = g_ptr_array_new_with_free_func(bt_object_release);
- if (!*output_ports) {
- ret = -1;
- goto end;
- }
-
- default_port = bt_component_add_port(component, *output_ports,
- BT_PORT_TYPE_OUTPUT, DEFAULT_OUTPUT_PORT_NAME);
- if (!default_port) {
- ret = -1;
- goto end;
- }
- bt_put(default_port);
-end:
- return ret;
-}
-
-BT_HIDDEN
+static
struct bt_port *bt_component_get_port(GPtrArray *ports, const char *name)
{
size_t i;
struct bt_port *ret_port = NULL;
+ 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);
}
BT_HIDDEN
+struct bt_port *bt_component_get_input_port(struct bt_component *comp,
+ const char *name)
+{
+ assert(comp);
+
+ return bt_component_get_port(comp->input_ports, name);
+}
+
+BT_HIDDEN
+struct bt_port *bt_component_get_output_port(struct bt_component *comp,
+ const char *name)
+{
+ assert(comp);
+
+ return bt_component_get_port(comp->output_ports, name);
+}
+
+static
struct bt_port *bt_component_get_port_at_index(GPtrArray *ports, int index)
{
struct bt_port *port = NULL;
}
BT_HIDDEN
-struct bt_port *bt_component_add_port(
- struct bt_component *component,GPtrArray *ports,
- enum bt_port_type port_type, const char *name)
+struct bt_port *bt_component_get_input_port_at_index(struct bt_component *comp,
+ int index)
{
- size_t i;
- struct bt_port *new_port = NULL;
+ assert(comp);
- if (!component->initializing || !name || *name == '\0') {
- goto end;
- }
+ return bt_component_get_port_at_index(comp->input_ports, index);
+}
- /* 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);
+BT_HIDDEN
+struct bt_port *bt_component_get_output_port_at_index(struct bt_component *comp,
+ int index)
+{
+ assert(comp);
- port_name = bt_port_get_name(port);
- if (!port_name) {
- continue;
- }
+ return bt_component_get_port_at_index(comp->output_ports, index);
+}
- if (!strcmp(name, port_name)) {
- /* Port name clash, abort. */
- goto end;
- }
- }
+BT_HIDDEN
+struct bt_port *bt_component_add_input_port(
+ struct bt_component *component, const char *name)
+{
+ return bt_component_add_port(component, component->input_ports,
+ BT_PORT_TYPE_INPUT, name);
+}
- new_port = bt_port_create(component, port_type, name);
- if (!new_port) {
- goto end;
+BT_HIDDEN
+struct bt_port *bt_component_add_output_port(
+ struct bt_component *component, const char *name)
+{
+ return bt_component_add_port(component, component->output_ports,
+ BT_PORT_TYPE_OUTPUT, name);
+}
+
+static
+void bt_component_remove_port_at_index(struct bt_component *component,
+ GPtrArray *ports, size_t index)
+{
+ struct bt_port *port;
+ struct bt_graph *graph;
+
+ assert(ports);
+ assert(index < ports->len);
+ port = g_ptr_array_index(ports, index);
+
+ /* Disconnect both ports of this port's connection, if any */
+ if (port->connection) {
+ bt_connection_disconnect_ports(port->connection);
}
+ /* Remove from parent's array of ports (weak refs) */
+ g_ptr_array_remove_index(ports, index);
+
+ /* Detach port from its component parent */
+ BT_PUT(port->base.parent);
+
/*
- * No name clash, add the port.
- * The component is now the port's parent; it should _not_
- * hold a reference to the port since the port's lifetime
- * is now protected by the component's own lifetime.
+ * Notify the graph's creator that a port is removed.
*/
- g_ptr_array_add(ports, new_port);
-end:
- return new_port;
+ graph = bt_component_get_graph(component);
+ if (graph) {
+ bt_graph_notify_port_removed(graph, component, port);
+ BT_PUT(graph);
+ }
}
BT_HIDDEN
enum bt_component_status bt_component_remove_port(
- struct bt_component *component, GPtrArray *ports,
- const char *name)
+ struct bt_component *component, struct bt_port *port)
{
size_t i;
enum bt_component_status status = BT_COMPONENT_STATUS_OK;
+ GPtrArray *ports = NULL;
- if (!component->initializing || !name) {
+ if (!component || !port) {
status = BT_COMPONENT_STATUS_INVALID;
goto end;
}
- for (i = 0; i < ports->len; i++) {
- const char *port_name;
- struct bt_port *port = g_ptr_array_index(ports, i);
+ 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;
+ }
- port_name = bt_port_get_name(port);
- if (!port_name) {
- continue;
- }
+ assert(ports);
- if (!strcmp(name, port_name)) {
- g_ptr_array_remove_index(ports, i);
+ 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_at_index(component,
+ ports, i);
goto end;
}
}
+
status = BT_COMPONENT_STATUS_NOT_FOUND;
end:
return status;
}
BT_HIDDEN
-enum bt_component_status bt_component_new_connection(
- struct bt_component *component, struct bt_port *own_port,
- struct bt_connection *connection)
+enum bt_component_status bt_component_accept_port_connection(
+ struct bt_component *comp, struct bt_port *self_port,
+ struct bt_port *other_port)
{
enum bt_component_status status = BT_COMPONENT_STATUS_OK;
- if (component->class->methods.new_connection_method) {
- status = component->class->methods.new_connection_method(
- own_port, connection);
+ assert(comp);
+ assert(self_port);
+ assert(other_port);
+
+ if (comp->class->methods.accept_port_connection) {
+ status = comp->class->methods.accept_port_connection(
+ bt_private_component_from_component(comp),
+ bt_private_port_from_port(self_port),
+ other_port);
}
return status;
}
+
+BT_HIDDEN
+void bt_component_port_disconnected(struct bt_component *comp,
+ struct bt_port *port)
+{
+ assert(comp);
+ assert(port);
+
+ if (comp->class->methods.port_disconnected) {
+ comp->class->methods.port_disconnected(
+ bt_private_component_from_component(comp),
+ bt_private_port_from_port(port));
+ }
+}