lib: graph: add "self" and some "private" APIs
[babeltrace.git] / lib / graph / component.c
index 6da601c89295975edc8a86228b35fed59408c4af..7bca1bfd7ef542fcc50aea65094c2c48fece7cbb 100644 (file)
 #define BT_LOG_TAG "COMP"
 #include <babeltrace/lib-logging-internal.h>
 
-#include <babeltrace/graph/private-component.h>
+#include <babeltrace/graph/self-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/graph/port-internal.h>
 #include <babeltrace/babeltrace-internal.h>
 #include <babeltrace/compiler-internal.h>
 #include <babeltrace/object.h>
@@ -44,6 +43,7 @@
 #include <babeltrace/values.h>
 #include <babeltrace/values-internal.h>
 #include <babeltrace/assert-internal.h>
+#include <babeltrace/assert-pre-internal.h>
 #include <stdint.h>
 #include <inttypes.h>
 
@@ -63,10 +63,51 @@ void (*component_destroy_funcs[])(struct bt_component *) = {
 };
 
 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) {
@@ -77,16 +118,16 @@ void bt_component_destroy(struct bt_object *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_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.
+        * 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++;
        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.");
@@ -99,17 +140,13 @@ void bt_component_destroy(struct bt_object *obj)
                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) {
@@ -120,81 +157,62 @@ void bt_component_destroy(struct bt_object *obj)
        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_object_put_ref(component_class);
+       BT_LOGD_STR("Putting component class.");
+       BT_OBJECT_PUT_REF_AND_RESET(component->class);
        g_free(component);
 }
 
-struct bt_component *bt_component_borrow_from_private(
-               struct bt_private_component *private_component)
-{
-       return (void *) private_component;
-}
-
 enum bt_component_class_type bt_component_get_class_type(
                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(
+struct bt_port *add_port(
                struct bt_component *component, GPtrArray *ports,
                enum bt_port_type port_type, const char *name, void *user_data)
 {
-       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;
-       }
+       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);
 
-       if (strlen(name) == 0) {
-               BT_LOGW_STR("Invalid parameter: name is an empty string.");
-               goto end;
-       }
+       // TODO: Validate that the name is not already used.
 
-       BT_LOGD("Adding port to component: comp-addr=%p, comp-name=\"%s\", "
+       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.");
+               BT_LOGE_STR("Cannot create port object.");
                goto end;
        }
 
@@ -215,35 +233,32 @@ struct bt_port *bt_component_add_port(
                BT_OBJECT_PUT_REF_AND_RESET(graph);
        }
 
-       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);
 
 end:
        return new_port;
 }
 
 BT_HIDDEN
-int64_t bt_component_get_input_port_count(struct bt_component *comp)
+uint64_t bt_component_get_input_port_count(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(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;
 
@@ -252,24 +267,23 @@ enum bt_component_status bt_component_create(
        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_shared_with_parent(&component->base,
-               bt_component_destroy);
+               destroy_component);
        component->class = bt_object_get_ref(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;
        }
 
@@ -277,7 +291,7 @@ enum bt_component_status bt_component_create(
                (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;
        }
 
@@ -285,7 +299,7 @@ enum bt_component_status bt_component_create(
                (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;
        }
 
@@ -293,72 +307,48 @@ enum bt_component_status bt_component_create(
                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_LIB_LOGD("Created empty component from component class: "
+               "%![cc-]+C, %![comp-]+c", component_class, component);
        BT_OBJECT_MOVE_REF(*user_component, component);
 
 end:
        bt_object_put_ref(component);
-       return status;
+       return ret;
 }
 
 const char *bt_component_get_name(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_class *bt_component_borrow_class(
                struct bt_component *component)
 {
-       return component ? bt_object_get_ref(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(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
@@ -376,24 +366,19 @@ bt_bool bt_component_graph_is_canceled(struct bt_component *component)
 }
 
 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_object_get_ref(port);
+               if (!strcmp(name, port->name->str)) {
+                       ret_port = port;
                        break;
                }
        }
@@ -402,81 +387,74 @@ struct bt_port *bt_component_get_port_by_name(GPtrArray *ports,
 }
 
 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_object_get_ref(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(
+struct bt_port_input *bt_component_add_input_port(
                struct bt_component *component, const char *name,
                void *user_data)
 {
-       /* 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 (void *)
+               add_port(component, component->input_ports,
+                       BT_PORT_TYPE_INPUT, name, user_data);
 }
 
 BT_HIDDEN
-struct bt_port *bt_component_add_output_port(
+struct bt_port_output *bt_component_add_output_port(
                struct bt_component *component, const char *name,
                void *user_data)
 {
-       /* 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 (void *)
+               add_port(component, component->output_ports,
+                       BT_PORT_TYPE_OUTPUT, name, user_data);
 }
 
 static
-void bt_component_remove_port_by_index(struct bt_component *component,
-               GPtrArray *ports, size_t index)
+void remove_port_by_index(struct bt_component *component,
+               GPtrArray *ports, uint64_t index)
 {
        struct bt_port *port;
        struct bt_graph *graph;
@@ -484,64 +462,80 @@ void bt_component_remove_port_by_index(struct bt_component *component,
        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));
+       BT_LIB_LOGD("Removing port from component: %![comp-]+c, %![port-]+p",
+               component, port);
 
        /* Disconnect both ports of this port's connection, if any */
        if (port->connection) {
                bt_connection_end(port->connection, true);
        }
 
-       /* Remove from parent's array of ports (weak refs) */
+       /*
+        * The port's current reference count can be 0 at this point,
+        * which means its parent (component) keeps it alive. We are
+        * about to remove the port from its parent's container (with
+        * the g_ptr_array_remove_index() call below), which in this
+        * case would destroy it. This is not good because we still
+        * need the port for the bt_graph_notify_port_removed() call
+        * below (in which its component is `NULL` as expected because
+        * of the bt_object_set_parent() call below).
+        *
+        * To avoid a destroyed port during the notification callback,
+        * get a reference now, and put it (destroying the port if its
+        * reference count is 0 at this point) after notifying the
+        * private graph's user.
+        */
+       bt_object_get_no_null_check(&port->base);
+
+       /*
+        * Remove from parent's array of ports (weak refs). This never
+        * destroys the port object because its reference count is at
+        * least 1 thanks to the bt_object_get_no_null_check() call
+        * above.
+        */
        g_ptr_array_remove_index(ports, index);
 
        /* Detach port from its component parent */
-       BT_OBJECT_PUT_REF_AND_RESET(port->base.parent);
+       bt_object_set_parent(&port->base, NULL);
 
        /*
         * Notify the graph's creator that a port is removed.
         */
-       graph = bt_object_get_ref(bt_component_borrow_graph(component));
+       graph = bt_component_borrow_graph(component);
        if (graph) {
                bt_graph_notify_port_removed(graph, component, port);
-               BT_OBJECT_PUT_REF_AND_RESET(graph);
        }
 
-       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_LIB_LOGD("Removed port from component: %![comp-]+c, %![port-]+p",
+               component, port);
+
+       /*
+        * Put the local reference. If this port's reference count was 0
+        * when entering this function, it is 1 now, so it is destroyed
+        * immediately.
+        */
+       bt_object_put_no_null_check(&port->base);
 }
 
 BT_HIDDEN
-enum bt_component_status bt_component_remove_port(
-               struct bt_component *component, struct bt_port *port)
+void bt_component_remove_port(struct bt_component *component,
+               struct bt_port *port)
 {
-       size_t i;
-       enum bt_component_status status = BT_COMPONENT_STATUS_OK;
+       uint64_t i;
        GPtrArray *ports = NULL;
 
-       if (!component) {
-               BT_LOGW_STR("Invalid parameter: component is NULL.");
-               status = BT_COMPONENT_STATUS_INVALID;
-               goto end;
-       }
-
-       if (!port) {
-               BT_LOGW_STR("Invalid parameter: port is NULL.");
-               status = BT_COMPONENT_STATUS_INVALID;
-               goto end;
-       }
+       BT_ASSERT(component);
+       BT_ASSERT(port);
 
-       if (bt_port_get_type(port) == BT_PORT_TYPE_INPUT) {
+       switch (port->type) {
+       case BT_PORT_TYPE_INPUT:
                ports = component->input_ports;
-       } else if (bt_port_get_type(port) == BT_PORT_TYPE_OUTPUT) {
+               break;
+       case BT_PORT_TYPE_OUTPUT:
                ports = component->output_ports;
+               break;
+       default:
+               abort();
        }
 
        BT_ASSERT(ports);
@@ -550,74 +544,168 @@ enum bt_component_status bt_component_remove_port(
                struct bt_port *cur_port = g_ptr_array_index(ports, i);
 
                if (cur_port == port) {
-                       bt_component_remove_port_by_index(component,
+                       remove_port_by_index(component,
                                ports, i);
                        goto end;
                }
        }
 
-       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));
+       BT_LIB_LOGW("Port to remove from component was not found: "
+               "%![comp-]+c, %![port-]+p", component, port);
 
 end:
-       return status;
+       return;
 }
 
 BT_HIDDEN
-enum bt_component_status bt_component_accept_port_connection(
+enum bt_self_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;
+       typedef enum bt_self_component_status (*method_t)(
+               void *, void *, 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);
+       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.accept_output_port_connection;
+                       break;
+               default:
+                       abort();
+               }
+
+               break;
+       }
+       case BT_COMPONENT_CLASS_TYPE_FILTER:
+       {
+               struct bt_component_class_filter *flt_cc = (void *) comp->class;
+
+               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();
+               }
+
+               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.accept_input_port_connection;
+                       break;
+               default:
+                       abort();
+               }
+
+               break;
+       }
+       default:
+               abort();
+       }
+
+       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, other_port);
                BT_LOGD("User method returned: status=%s",
-                       bt_component_status_string(status));
+                       bt_self_component_status_string(status));
        }
 
        return status;
 }
 
 BT_HIDDEN
-enum bt_component_status bt_component_port_connected(struct bt_component *comp,
-               struct bt_port *self_port, struct bt_port *other_port)
+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 *, 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.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));
-               status = comp->class->methods.port_connected(
-                       bt_private_component_from_component(comp),
-                       bt_private_port_from_port(self_port), other_port);
+       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;
+
+               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();
+               }
+
+               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();
+               }
+
+               break;
+       }
+       default:
+               abort();
+       }
+
+       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, other_port);
+               BT_LOGD("User method returned: status=%s",
+                       bt_self_component_status_string(status));
        }
 
        return status;
@@ -627,18 +715,67 @@ BT_HIDDEN
 void bt_component_port_disconnected(struct bt_component *comp,
                struct bt_port *port)
 {
+       typedef void (*method_t)(void *, void *);
+
+       method_t method = NULL;
+
        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));
+       switch (comp->class->type) {
+       case BT_COMPONENT_CLASS_TYPE_SOURCE:
+       {
+               struct bt_component_class_source *src_cc = (void *) comp->class;
+
+               switch (port->type) {
+               case BT_PORT_TYPE_OUTPUT:
+                       method = (method_t) src_cc->methods.output_port_disconnected;
+                       break;
+               default:
+                       abort();
+               }
+
+               break;
+       }
+       case BT_COMPONENT_CLASS_TYPE_FILTER:
+       {
+               struct bt_component_class_filter *flt_cc = (void *) comp->class;
+
+               switch (port->type) {
+               case BT_PORT_TYPE_INPUT:
+                       method = (method_t) flt_cc->methods.input_port_disconnected;
+                       break;
+               case BT_PORT_TYPE_OUTPUT:
+                       method = (method_t) flt_cc->methods.output_port_disconnected;
+                       break;
+               default:
+                       abort();
+               }
+
+               break;
+       }
+       case BT_COMPONENT_CLASS_TYPE_SINK:
+       {
+               struct bt_component_class_sink *sink_cc = (void *) comp->class;
+
+               switch (port->type) {
+               case BT_PORT_TYPE_INPUT:
+                       method = (method_t) sink_cc->methods.input_port_disconnected;
+                       break;
+               default:
+                       abort();
+               }
+
+               break;
+       }
+       default:
+               abort();
+       }
+
+       if (method) {
+               BT_LIB_LOGD("Calling user's \"port disconnected\" method: "
+                       "%![comp-]+c, %![port-]+p", comp, port);
+               method(comp, port);
        }
 }
 
@@ -653,18 +790,16 @@ void bt_component_add_destroy_listener(struct bt_component *component,
        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);
@@ -677,11 +812,9 @@ void bt_component_remove_destroy_listener(struct bt_component *component,
                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);
                }
        }
 }
This page took 0.03622 seconds and 4 git commands to generate.