lib: update and simplify the `bt_object` API
[babeltrace.git] / lib / graph / component.c
index 8664e3b423fb4a19ef2f70dc73adf2731ee422e6..8ffab8e0b20fe5d8fa7544f0c5ca4bfeb8c7b901 100644 (file)
 #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/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 <stdint.h>
 #include <inttypes.h>
 
 static
 struct bt_component * (* const component_create_funcs[])(
-               struct bt_component_class *, struct bt_value *) = {
+               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,
@@ -85,7 +86,7 @@ void bt_component_destroy(struct bt_object *obj)
         * bt_put(): 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),
@@ -105,10 +106,11 @@ void bt_component_destroy(struct bt_object *obj)
        component_class = component->class;
 
        /*
-        * User data is destroyed first, followed by the concrete component
-        * instance.
+        * 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->class->methods.finalize) {
+       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));
@@ -142,10 +144,10 @@ void bt_component_destroy(struct bt_object *obj)
        g_free(component);
 }
 
-struct bt_component *bt_component_from_private_component(
+struct bt_component *bt_component_borrow_from_private(
                struct bt_private_component *private_component)
 {
-       return bt_get(bt_component_from_private(private_component));
+       return (void *) private_component;
 }
 
 enum bt_component_class_type bt_component_get_class_type(
@@ -184,7 +186,7 @@ struct bt_port *bt_component_add_port(
                struct bt_port *port = g_ptr_array_index(ports, i);
 
                port_name = bt_port_get_name(port);
-               assert(port_name);
+               BT_ASSERT(port_name);
 
                if (!strcmp(name, port_name)) {
                        /* Port name clash, abort. */
@@ -229,94 +231,65 @@ end:
 BT_HIDDEN
 int64_t bt_component_get_input_port_count(struct bt_component *comp)
 {
-       assert(comp);
+       BT_ASSERT(comp);
        return (int64_t) comp->input_ports->len;
 }
 
 BT_HIDDEN
 int64_t bt_component_get_output_port_count(struct bt_component *comp)
 {
-       assert(comp);
+       BT_ASSERT(comp);
        return (int64_t) comp->output_ports->len;
 }
 
-struct bt_component *bt_component_create_with_init_method_data(
-               struct bt_component_class *component_class, const char *name,
-               struct bt_value *params, void *init_method_data)
+BT_HIDDEN
+enum bt_component_status bt_component_create(
+               struct bt_component_class *component_class,
+               const char *name, struct bt_component **user_component)
 {
-       int ret;
+       enum bt_component_status status = BT_COMPONENT_STATUS_OK;
        struct bt_component *component = NULL;
        enum bt_component_class_type type;
 
-       bt_get(params);
-
-       if (!component_class) {
-               BT_LOGW_STR("Invalid parameter: component class is NULL.");
-               goto end;
-       }
+       BT_ASSERT(user_component);
+       BT_ASSERT(component_class);
+       BT_ASSERT(name);
 
        type = bt_component_class_get_type(component_class);
-       if (type <= BT_COMPONENT_CLASS_TYPE_UNKNOWN ||
-                       type > BT_COMPONENT_CLASS_TYPE_FILTER) {
-               BT_LOGW("Invalid parameter: unknown component class type: "
-                       "type=%s", bt_component_class_type_string(type));
-               goto end;
-       }
-
-       BT_LOGD("Creating component from component class: "
-               "comp-cls-addr=%p, comp-cls-type=%s, name=\"%s\", "
-               "params-addr=%p, init-method-data-addr=%p",
-               component_class, bt_component_class_type_string(type),
-               name, params, init_method_data);
-
-       /*
-        * Parameters must be a map value, but we create a convenient
-        * empty one if it's NULL.
-        */
-       if (params) {
-               if (!bt_value_is_map(params)) {
-                       BT_LOGW("Invalid parameter: initialization parameters must be a map value: "
-                               "type=%s",
-                               bt_value_type_string(bt_value_get_type(params)));
-                       goto end;
-               }
-       } else {
-               params = bt_value_map_create();
-               if (!params) {
-                       BT_LOGE_STR("Cannot create map value object.");
-                       goto end;
-               }
-       }
-
-       component = component_create_funcs[type](component_class, params);
+       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);
+       component = component_create_funcs[type](component_class);
        if (!component) {
                BT_LOGE_STR("Cannot create specific component object.");
+               status = BT_COMPONENT_STATUS_NOMEM;
                goto end;
        }
 
-       bt_object_init(component, bt_component_destroy);
+       bt_object_init_shared_with_parent(&component->base,
+               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_LOGE_STR("Failed to allocate one GString.");
-               BT_PUT(component);
+               status = BT_COMPONENT_STATUS_NOMEM;
                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.");
-               BT_PUT(component);
+               status = BT_COMPONENT_STATUS_NOMEM;
                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.");
-               BT_PUT(component);
+               status = BT_COMPONENT_STATUS_NOMEM;
                goto end;
        }
 
@@ -324,44 +297,19 @@ struct bt_component *bt_component_create_with_init_method_data(
                sizeof(struct bt_component_destroy_listener));
        if (!component->destroy_listeners) {
                BT_LOGE_STR("Failed to allocate one GArray.");
-               BT_PUT(component);
+               status = BT_COMPONENT_STATUS_NOMEM;
                goto end;
        }
 
-       if (component_class->methods.init) {
-               BT_LOGD_STR("Calling user's initialization method.");
-               ret = component_class->methods.init(
-                       bt_private_component_from_component(component), params,
-                       init_method_data);
-               BT_LOGD("User method returned: status=%s",
-                       bt_component_status_string(ret));
-               if (ret != BT_COMPONENT_STATUS_OK) {
-                       BT_LOGW_STR("Initialization method failed.");
-                       BT_PUT(component);
-                       goto end;
-               }
-       }
-
-       BT_LOGD_STR("Freezing component class.");
-       bt_component_class_freeze(component->class);
-       BT_LOGD("Created component from component class: "
-               "comp-cls-addr=%p, comp-cls-type=%s, name=\"%s\", "
-               "params-addr=%p, init-method-data-addr=%p, comp-addr=%p",
-               component_class, bt_component_class_type_string(type),
-               name, params, init_method_data, component);
+       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);
 
 end:
-       bt_put(params);
-       return component;
-}
-
-struct bt_component *bt_component_create(
-               struct bt_component_class *component_class, const char *name,
-               struct bt_value *params)
-{
-       /* bt_component_create_with_init_method_data() logs details */
-       return bt_component_create_with_init_method_data(component_class, name,
-               params, NULL);
+       bt_put(component);
+       return status;
 }
 
 const char *bt_component_get_name(struct bt_component *component)
@@ -389,7 +337,7 @@ void *bt_private_component_get_user_data(
                struct bt_private_component *private_component)
 {
        struct bt_component *component =
-               bt_component_from_private(private_component);
+               bt_component_borrow_from_private(private_component);
 
        return component ? component->user_data : NULL;
 }
@@ -399,7 +347,7 @@ enum bt_component_status bt_private_component_set_user_data(
                void *data)
 {
        struct bt_component *component =
-               bt_component_from_private(private_component);
+               bt_component_borrow_from_private(private_component);
        enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
 
        if (!component) {
@@ -421,19 +369,13 @@ BT_HIDDEN
 void bt_component_set_graph(struct bt_component *component,
                struct bt_graph *graph)
 {
-       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);
+       bt_object_set_parent(&component->base,
+               graph ? &graph->base : NULL);
 }
 
-struct bt_graph *bt_component_get_graph(
-               struct bt_component *component)
+struct bt_graph *bt_component_borrow_graph(struct bt_component *component)
 {
-       return (struct bt_graph *) bt_object_get_parent(&component->base);
+       return (struct bt_graph *) bt_object_borrow_parent(&component->base);
 }
 
 static
@@ -443,7 +385,7 @@ struct bt_port *bt_component_get_port_by_name(GPtrArray *ports,
        size_t i;
        struct bt_port *ret_port = NULL;
 
-       assert(name);
+       BT_ASSERT(name);
 
        for (i = 0; i < ports->len; i++) {
                struct bt_port *port = g_ptr_array_index(ports, i);
@@ -466,7 +408,7 @@ BT_HIDDEN
 struct bt_port *bt_component_get_input_port_by_name(struct bt_component *comp,
                const char *name)
 {
-       assert(comp);
+       BT_ASSERT(comp);
 
        return bt_component_get_port_by_name(comp->input_ports, name);
 }
@@ -475,7 +417,7 @@ BT_HIDDEN
 struct bt_port *bt_component_get_output_port_by_name(struct bt_component *comp,
                const char *name)
 {
-       assert(comp);
+       BT_ASSERT(comp);
 
        return bt_component_get_port_by_name(comp->output_ports, name);
 }
@@ -501,7 +443,7 @@ BT_HIDDEN
 struct bt_port *bt_component_get_input_port_by_index(struct bt_component *comp,
                uint64_t index)
 {
-       assert(comp);
+       BT_ASSERT(comp);
 
        return bt_component_get_port_by_index(comp->input_ports, index);
 }
@@ -510,7 +452,7 @@ BT_HIDDEN
 struct bt_port *bt_component_get_output_port_by_index(struct bt_component *comp,
                uint64_t index)
 {
-       assert(comp);
+       BT_ASSERT(comp);
 
        return bt_component_get_port_by_index(comp->output_ports, index);
 }
@@ -542,8 +484,8 @@ void bt_component_remove_port_by_index(struct bt_component *component,
        struct bt_port *port;
        struct bt_graph *graph;
 
-       assert(ports);
-       assert(index < ports->len);
+       BT_ASSERT(ports);
+       BT_ASSERT(index < ports->len);
        port = g_ptr_array_index(ports, index);
 
        BT_LOGD("Removing port from component: "
@@ -605,7 +547,7 @@ enum bt_component_status bt_component_remove_port(
                ports = component->output_ports;
        }
 
-       assert(ports);
+       BT_ASSERT(ports);
 
        for (i = 0; i < ports->len; i++) {
                struct bt_port *cur_port = g_ptr_array_index(ports, i);
@@ -635,9 +577,9 @@ enum bt_component_status bt_component_accept_port_connection(
 {
        enum bt_component_status status = BT_COMPONENT_STATUS_OK;
 
-       assert(comp);
-       assert(self_port);
-       assert(other_port);
+       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: "
@@ -662,9 +604,9 @@ BT_HIDDEN
 void bt_component_port_connected(struct bt_component *comp,
                struct bt_port *self_port, struct bt_port *other_port)
 {
-       assert(comp);
-       assert(self_port);
-       assert(other_port);
+       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: "
@@ -684,8 +626,8 @@ BT_HIDDEN
 void bt_component_port_disconnected(struct bt_component *comp,
                struct bt_port *port)
 {
-       assert(comp);
-       assert(port);
+       BT_ASSERT(comp);
+       BT_ASSERT(port);
 
        if (comp->class->methods.port_disconnected) {
                BT_LOGD("Calling user's \"port disconnected\" method: "
@@ -705,8 +647,8 @@ void bt_component_add_destroy_listener(struct bt_component *component,
 {
        struct bt_component_destroy_listener listener;
 
-       assert(component);
-       assert(func);
+       BT_ASSERT(component);
+       BT_ASSERT(func);
        listener.func = func;
        listener.data = data;
        g_array_append_val(component->destroy_listeners, listener);
@@ -723,8 +665,8 @@ void bt_component_remove_destroy_listener(struct bt_component *component,
 {
        size_t i;
 
-       assert(component);
-       assert(func);
+       BT_ASSERT(component);
+       BT_ASSERT(func);
 
        for (i = 0; i < component->destroy_listeners->len; i++) {
                struct bt_component_destroy_listener *listener =
This page took 0.029254 seconds and 4 git commands to generate.