Rename <babeltrace/component/...> -> <babeltrace/graph/...>
[babeltrace.git] / lib / component / component.c
index 31aad81be46bb3f60bde84d3a04cdd0864d817be..e8c4b5af7c14e2167386c9d1886bfcd2ef20a442 100644 (file)
  * 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/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/ref.h>
@@ -46,6 +50,13 @@ struct bt_component * (* const component_create_funcs[])(
        [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 *) = {
@@ -71,33 +82,32 @@ void bt_component_destroy(struct bt_object *obj)
         * 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->destroy = destroy;
-end:
-       return ret;
+       return bt_get(bt_component_from_private(private_component));
 }
 
 enum bt_component_class_type bt_component_get_class_type(
@@ -106,78 +116,74 @@ 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(
@@ -187,6 +193,7 @@ 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;
@@ -204,16 +211,59 @@ struct bt_component *bt_component_create_with_init_method_data(
        }
 
        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) {
@@ -231,6 +281,7 @@ struct bt_component *bt_component_create_with_init_method_data(
 
        bt_component_class_freeze(component->class);
 end:
+       bt_put(default_port);
        return component;
 }
 
@@ -276,15 +327,21 @@ struct bt_component_class *bt_component_get_class(
        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) {
@@ -298,11 +355,16 @@ end:
 }
 
 BT_HIDDEN
-enum bt_component_status bt_component_set_graph(struct bt_component *component,
+void bt_component_set_graph(struct bt_component *component,
                struct bt_graph *graph)
 {
-       bt_object_set_parent(component, &graph->base);
-       return BT_COMPONENT_STATUS_OK;
+       struct bt_object *parent = bt_object_get_parent(&component->base);
+
+       assert(!parent || parent == &graph->base);
+       if (!parent) {
+               bt_object_set_parent(component, &graph->base);
+       }
+       bt_put(parent);
 }
 
 struct bt_graph *bt_component_get_graph(
@@ -311,62 +373,14 @@ struct bt_graph *bt_component_get_graph(
        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_port_create(component, BT_PORT_TYPE_INPUT,
-                       DEFAULT_INPUT_PORT_NAME);
-       if (!default_port) {
-               ret = -1;
-               goto end;
-       }
-
-       g_ptr_array_add(*input_ports, 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_port_create(component, BT_PORT_TYPE_OUTPUT,
-                       DEFAULT_OUTPUT_PORT_NAME);
-       if (!default_port) {
-               ret = -1;
-               goto end;
-       }
-
-       g_ptr_array_add(*output_ports, 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);
@@ -385,6 +399,24 @@ struct bt_port *bt_component_get_port(GPtrArray *ports, const char *name)
 }
 
 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;
@@ -399,77 +431,138 @@ end:
 }
 
 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;
+       assert(comp);
 
-       if (!component->initializing || !name || *name == '\0') {
-               new_port = NULL;
-               goto end;
-       }
+       return bt_component_get_port_at_index(comp->input_ports, index);
+}
 
-       new_port = bt_port_create(component, port_type, name);
-       if (!new_port) {
-               goto end;
-       }
+BT_HIDDEN
+struct bt_port *bt_component_get_output_port_at_index(struct bt_component *comp,
+               int index)
+{
+       assert(comp);
 
-       /* 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);
+       return bt_component_get_port_at_index(comp->output_ports, index);
+}
 
-               port_name = bt_port_get_name(port);
-               if (!port_name) {
-                       continue;
-               }
+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);
+}
 
-               if (!strcmp(name, port_name)) {
-                       /* Port name clash, abort. */
-                       goto error;
-               }
+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, component);
        }
 
-       /* No name clash, add the port. */
-       g_ptr_array_add(ports, bt_get(new_port));
-end:
-       return new_port;
-error:
-       BT_PUT(new_port);
-       goto end;
+       /* 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);
+
+       /*
+        * 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);
+       }
 }
 
 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_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;
+
+       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));
+       }
+}
This page took 0.029863 seconds and 4 git commands to generate.