From: Philippe Proulx Date: Thu, 8 Jun 2017 02:25:48 +0000 (-0400) Subject: Add bt_graph_add_component(), make bt_component_create() internal X-Git-Url: http://drtracing.org/?a=commitdiff_plain;h=36712f1d9ad9269638e493ca36a50979fe4da989;p=deliverable%2Fbabeltrace.git Add bt_graph_add_component(), make bt_component_create() internal With this patch, you can only instantiate a component class through an existing graph. This can guarantee to the user (component class developer) that, when the component class's initialization method is called, the component always belongs to a graph. This simplifies things, now and in the future. For example, it is possible to cancel the graph during the execution of bt_graph_add_component() so that the user method knows if it should retry now or return an error when the graph is canceled. bt_graph_add_component() returns BT_GRAPH_STATUS_CANCELED if the graph is canceled. If the user's initialization method fails, its return component status is converted to the appropriate graph status. Another advantage of adding a component to a graph is that, if you add a "port added" graph listener, it is guaranteed that the listener is called even for the initial ports of a component. This was not possible before. This patch also makes a component's name mandatory, and bt_graph_add_component() ensures that there are components sharing the same name part of a given graph. This is a constraint similar to the fact that all the ports of a component must have a unique name. It should help to the implementation of a function to retrieve a component by name from a graph in the future. We do not check that a graph has or not "loose", disconnected components in bt_graph_consume(). This is not a change because any component can remove all its ports once connected once and become loose. A graph with floating/loose components is said to be disconnected in classical graph theory. This is not a problem for the moment, as the connected components can still interact. The disconnected components should probably be marked and then destroyed in bt_graph_consume() and/or in a dedicated garbage collecting function if needed (bt_graph_remove_disconnected_components() for example). This patch also makes successfully user-initialized components marked as such so that the user's finalization method is not called if its initialization method failed. In other words, the initialization method is responsible for any cleanup if it's about to fail. Signed-off-by: Philippe Proulx Signed-off-by: Jérémie Galarneau --- diff --git a/cli/babeltrace.c b/cli/babeltrace.c index b68ddf153..4e35b8b6d 100644 --- a/cli/babeltrace.c +++ b/cli/babeltrace.c @@ -1418,6 +1418,11 @@ void graph_port_added_listener(struct bt_port *port, void *data) "comp-name=\"%s\", port-addr=%p, port-name=\"%s\"", comp, comp ? bt_component_get_name(comp) : "", port, bt_port_get_name(port)); + + if (!ctx->connect_ports) { + goto end; + } + if (!comp) { BT_LOGW_STR("Port has no component."); goto end; @@ -1598,9 +1603,9 @@ int cmd_run_ctx_create_components_from_config_components( goto error; } - comp = bt_component_create(comp_cls, - cfg_comp->instance_name->str, cfg_comp->params); - if (!comp) { + ret = bt_graph_add_component(ctx->graph, comp_cls, + cfg_comp->instance_name->str, cfg_comp->params, &comp); + if (ret) { BT_LOGE("Cannot create component: plugin-name=\"%s\", " "comp-cls-name=\"%s\", comp-cls-type=%d, " "comp-name=\"%s\"", @@ -1744,8 +1749,6 @@ const char *bt_graph_status_str(enum bt_graph_status status) return "BT_GRAPH_STATUS_END"; case BT_GRAPH_STATUS_OK: return "BT_GRAPH_STATUS_OK"; - case BT_GRAPH_STATUS_ALREADY_IN_A_GRAPH: - return "BT_GRAPH_STATUS_ALREADY_IN_A_GRAPH"; case BT_GRAPH_STATUS_INVALID: return "BT_GRAPH_STATUS_INVALID"; case BT_GRAPH_STATUS_NO_SINK: diff --git a/include/babeltrace/graph/component-filter-internal.h b/include/babeltrace/graph/component-filter-internal.h index 3bf79a187..38a1a240a 100644 --- a/include/babeltrace/graph/component-filter-internal.h +++ b/include/babeltrace/graph/component-filter-internal.h @@ -46,7 +46,7 @@ struct bt_component_filter { */ BT_HIDDEN struct bt_component *bt_component_filter_create( - struct bt_component_class *class, struct bt_value *params); + struct bt_component_class *class); BT_HIDDEN void bt_component_filter_destroy(struct bt_component *component); diff --git a/include/babeltrace/graph/component-internal.h b/include/babeltrace/graph/component-internal.h index f78c468b0..35a353a1b 100644 --- a/include/babeltrace/graph/component-internal.h +++ b/include/babeltrace/graph/component-internal.h @@ -64,6 +64,8 @@ struct bt_component { /* Array of struct bt_component_destroy_listener */ GArray *destroy_listeners; + + bool initialized; }; static inline @@ -87,6 +89,11 @@ struct bt_graph *bt_component_borrow_graph(struct bt_component *comp) return (void *) comp->base.parent; } +BT_HIDDEN +enum bt_component_status bt_component_create( + struct bt_component_class *component_class, + const char *name, struct bt_component **component); + BT_HIDDEN enum bt_component_status bt_component_accept_port_connection( struct bt_component *component, struct bt_port *self_port, diff --git a/include/babeltrace/graph/component-sink-internal.h b/include/babeltrace/graph/component-sink-internal.h index cffb9a964..c1e7a4548 100644 --- a/include/babeltrace/graph/component-sink-internal.h +++ b/include/babeltrace/graph/component-sink-internal.h @@ -49,7 +49,7 @@ struct bt_component_sink { */ BT_HIDDEN struct bt_component *bt_component_sink_create( - struct bt_component_class *class, struct bt_value *params); + struct bt_component_class *class); BT_HIDDEN void bt_component_sink_destroy(struct bt_component *component); diff --git a/include/babeltrace/graph/component-source-internal.h b/include/babeltrace/graph/component-source-internal.h index fde158453..98b523ce2 100644 --- a/include/babeltrace/graph/component-source-internal.h +++ b/include/babeltrace/graph/component-source-internal.h @@ -46,7 +46,7 @@ struct bt_component_source { */ BT_HIDDEN struct bt_component *bt_component_source_create( - struct bt_component_class *class, struct bt_value *params); + struct bt_component_class *class); BT_HIDDEN void bt_component_source_destroy(struct bt_component *component); diff --git a/include/babeltrace/graph/component.h b/include/babeltrace/graph/component.h index 31fde560a..e9ee50936 100644 --- a/include/babeltrace/graph/component.h +++ b/include/babeltrace/graph/component.h @@ -43,22 +43,6 @@ struct bt_component; struct bt_value; struct bt_port; -/** - * Create an instance of a component from a component class. - * - * @param component_class Component class of which to create an instance - * @param name Name of the new component instance, optional - * @param params A dictionary of component parameters - * @returns Returns a pointer to a new component instance - */ -extern struct bt_component *bt_component_create( - struct bt_component_class *component_class, const char *name, - struct bt_value *params); - -extern 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); - /** * Get component's name. * diff --git a/include/babeltrace/graph/graph-internal.h b/include/babeltrace/graph/graph-internal.h index f8f0d1a17..d41864259 100644 --- a/include/babeltrace/graph/graph-internal.h +++ b/include/babeltrace/graph/graph-internal.h @@ -101,8 +101,6 @@ const char *bt_graph_status_string(enum bt_graph_status status) return "BT_GRAPH_STATUS_END"; case BT_GRAPH_STATUS_OK: return "BT_GRAPH_STATUS_OK"; - case BT_GRAPH_STATUS_ALREADY_IN_A_GRAPH: - return "BT_GRAPH_STATUS_ALREADY_IN_A_GRAPH"; case BT_GRAPH_STATUS_INVALID: return "BT_GRAPH_STATUS_INVALID"; case BT_GRAPH_STATUS_NO_SINK: diff --git a/include/babeltrace/graph/graph.h b/include/babeltrace/graph/graph.h index a2dfbd823..a5077c490 100644 --- a/include/babeltrace/graph/graph.h +++ b/include/babeltrace/graph/graph.h @@ -46,8 +46,6 @@ enum bt_graph_status { /** Downstream component does not support multiple inputs. */ BT_GRAPH_STATUS_END = 1, BT_GRAPH_STATUS_OK = 0, - /** Component is already part of another graph. */ - BT_GRAPH_STATUS_ALREADY_IN_A_GRAPH = -2, /** Invalid arguments. */ BT_GRAPH_STATUS_INVALID = -22, /** No sink in graph. */ @@ -71,6 +69,19 @@ typedef void (*bt_graph_ports_disconnected_listener)( extern struct bt_graph *bt_graph_create(void); +extern enum bt_graph_status bt_graph_add_component( + struct bt_graph *graph, + struct bt_component_class *component_class, + const char *name, struct bt_value *params, + struct bt_component **component); + +extern enum bt_graph_status bt_graph_add_component_with_init_method_data( + struct bt_graph *graph, + struct bt_component_class *component_class, + const char *name, struct bt_value *params, + void *init_method_data, + struct bt_component **component); + /** * Creates a connection between two components using the two ports specified * and adds the connection and components (if not already added) to the graph. diff --git a/include/babeltrace/object-internal.h b/include/babeltrace/object-internal.h index 2b368c551..9859e329d 100644 --- a/include/babeltrace/object-internal.h +++ b/include/babeltrace/object-internal.h @@ -64,7 +64,7 @@ void bt_object_release(void *ptr) obj->ref_count.count); #endif - if (obj && obj->release && !bt_object_get_ref_count(obj)) { + if (obj && obj->release && bt_object_get_ref_count(obj) == 0) { obj->release(obj); } } diff --git a/lib/graph/component.c b/lib/graph/component.c index 8664e3b42..ee8e94530 100644 --- a/lib/graph/component.c +++ b/lib/graph/component.c @@ -52,7 +52,7 @@ 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, @@ -105,10 +105,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)); @@ -240,57 +241,26 @@ int64_t bt_component_get_output_port_count(struct bt_component *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) +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; - } + assert(user_component); + assert(component_class); + 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; } @@ -300,7 +270,7 @@ struct bt_component *bt_component_create_with_init_method_data( 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; } @@ -308,7 +278,7 @@ struct bt_component *bt_component_create_with_init_method_data( bt_object_release); if (!component->input_ports) { BT_LOGE_STR("Failed to allocate one GPtrArray."); - BT_PUT(component); + status = BT_COMPONENT_STATUS_NOMEM; goto end; } @@ -316,7 +286,7 @@ struct bt_component *bt_component_create_with_init_method_data( bt_object_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 +294,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) @@ -421,13 +366,7 @@ 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, graph ? &graph->base : NULL); } struct bt_graph *bt_component_get_graph( diff --git a/lib/graph/filter.c b/lib/graph/filter.c index 78913517d..67beb4cd7 100644 --- a/lib/graph/filter.c +++ b/lib/graph/filter.c @@ -45,7 +45,7 @@ void bt_component_filter_destroy(struct bt_component *component) BT_HIDDEN struct bt_component *bt_component_filter_create( - struct bt_component_class *class, struct bt_value *params) + struct bt_component_class *class) { struct bt_component_filter *filter = NULL; diff --git a/lib/graph/graph.c b/lib/graph/graph.c index 5b5acae75..e7f8db3f3 100644 --- a/lib/graph/graph.c +++ b/lib/graph/graph.c @@ -37,6 +37,8 @@ #include #include #include +#include +#include #include #include @@ -208,8 +210,6 @@ enum bt_graph_status bt_graph_connect_ports(struct bt_graph *graph, struct bt_component *upstream_component = NULL; struct bt_component *downstream_component = NULL; enum bt_component_status component_status; - bt_bool upstream_was_already_in_graph; - bt_bool downstream_was_already_in_graph; if (!graph) { BT_LOGW_STR("Invalid parameter: graph is NULL."); @@ -291,24 +291,6 @@ enum bt_graph_status bt_graph_connect_ports(struct bt_graph *graph, upstream_component, bt_component_get_name(upstream_component), downstream_component, bt_component_get_name(downstream_component)); - /* Ensure the components are not already part of another graph. */ - upstream_graph = bt_component_get_graph(upstream_component); - if (upstream_graph && (graph != upstream_graph)) { - BT_LOGW("Invalid parameter: upstream port's component is already part of another graph: " - "other-graph-addr=%p", upstream_graph); - status = BT_GRAPH_STATUS_ALREADY_IN_A_GRAPH; - goto end; - } - upstream_was_already_in_graph = (graph == upstream_graph); - downstream_graph = bt_component_get_graph(downstream_component); - if (downstream_graph && (graph != downstream_graph)) { - BT_LOGW("Invalid parameter: downstream port's component is already part of another graph: " - "other-graph-addr=%p", downstream_graph); - status = BT_GRAPH_STATUS_ALREADY_IN_A_GRAPH; - goto end; - } - downstream_was_already_in_graph = (graph == downstream_graph); - /* * At this point the ports are not connected yet. Both * components need to accept an eventual connection to their @@ -363,26 +345,6 @@ enum bt_graph_status bt_graph_connect_ports(struct bt_graph *graph, */ g_ptr_array_add(graph->connections, connection); - if (!upstream_was_already_in_graph) { - g_ptr_array_add(graph->components, upstream_component); - bt_component_set_graph(upstream_component, graph); - } - if (!downstream_was_already_in_graph) { - g_ptr_array_add(graph->components, downstream_component); - bt_component_set_graph(downstream_component, graph); - if (bt_component_get_class_type(downstream_component) == - BT_COMPONENT_CLASS_TYPE_SINK) { - g_queue_push_tail(graph->sinks_to_consume, - downstream_component); - } - } - - /* - * The graph is now the parent of these components which - * garantees their existence for the duration of the graph's - * lifetime. - */ - /* * Notify both components that their port is connected. */ @@ -811,3 +773,175 @@ void bt_graph_remove_connection(struct bt_graph *graph, graph, connection); g_ptr_array_remove(graph->connections, connection); } + +enum bt_graph_status bt_graph_add_component_with_init_method_data( + struct bt_graph *graph, + struct bt_component_class *component_class, + const char *name, struct bt_value *params, + void *init_method_data, + struct bt_component **user_component) +{ + enum bt_graph_status graph_status = BT_GRAPH_STATUS_OK; + enum bt_component_status comp_status; + struct bt_component *component = NULL; + enum bt_component_class_type type; + size_t i; + + bt_get(params); + + if (!graph) { + BT_LOGW_STR("Invalid parameter: graph is NULL."); + graph_status = BT_GRAPH_STATUS_INVALID; + goto end; + } + + if (!component_class) { + BT_LOGW_STR("Invalid parameter: component class is NULL."); + graph_status = BT_GRAPH_STATUS_INVALID; + goto end; + } + + type = bt_component_class_get_type(component_class); + BT_LOGD("Adding component to graph: " + "graph-addr=%p, comp-cls-addr=%p, " + "comp-cls-type=%s, name=\"%s\", params-addr=%p, " + "init-method-data-addr=%p", + graph, component_class, bt_component_class_type_string(type), + name, params, init_method_data); + + if (!name) { + BT_LOGW_STR("Invalid parameter: name is NULL."); + graph_status = BT_GRAPH_STATUS_INVALID; + goto end; + } + + if (graph->canceled) { + BT_LOGW_STR("Invalid parameter: graph is canceled."); + graph_status = BT_GRAPH_STATUS_CANCELED; + goto end; + } + + if (type != BT_COMPONENT_CLASS_TYPE_SOURCE && + type != BT_COMPONENT_CLASS_TYPE_FILTER && + type != BT_COMPONENT_CLASS_TYPE_SINK) { + BT_LOGW("Invalid parameter: unknown component class type: " + "type=%d", type); + graph_status = BT_GRAPH_STATUS_INVALID; + goto end; + } + + for (i = 0; i < graph->components->len; i++) { + void *other_comp = graph->components->pdata[i]; + + if (strcmp(name, bt_component_get_name(other_comp)) == 0) { + BT_LOGW("Invalid parameter: another component with the same name already exists in the graph: " + "other-comp-addr=%p, name=\"%s\"", + other_comp, name); + graph_status = BT_GRAPH_STATUS_INVALID; + goto end; + } + } + + /* + * 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))); + graph_status = BT_GRAPH_STATUS_INVALID; + goto end; + } + } else { + params = bt_value_map_create(); + if (!params) { + BT_LOGE_STR("Cannot create map value object."); + graph_status = BT_GRAPH_STATUS_NOMEM; + goto end; + } + } + + comp_status = bt_component_create(component_class, name, &component); + if (comp_status != BT_COMPONENT_STATUS_OK) { + BT_LOGE("Cannot create empty component object: status=%s", + bt_component_status_string(comp_status)); + graph_status = bt_graph_status_from_component_status( + comp_status); + goto end; + } + + /* + * The user's initialization method needs to see that this + * component is part of the graph. If the user method fails, we + * immediately remove the component from the graph's components. + */ + g_ptr_array_add(graph->components, component); + bt_component_set_graph(component, graph); + + if (component_class->methods.init) { + BT_LOGD_STR("Calling user's initialization method."); + comp_status = 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(comp_status)); + if (comp_status != BT_COMPONENT_STATUS_OK) { + BT_LOGW_STR("Initialization method failed."); + graph_status = bt_graph_status_from_component_status( + comp_status); + bt_component_set_graph(component, NULL); + g_ptr_array_remove_fast(graph->components, component); + goto end; + } + } + + /* + * Mark the component as initialized so that its finalization + * method is called when it is destroyed. + */ + component->initialized = true; + + /* + * If it's a sink component, it needs to be part of the graph's + * sink queue to be consumed by bt_graph_consume(). + */ + if (bt_component_is_sink(component)) { + g_queue_push_tail(graph->sinks_to_consume, component); + } + + /* + * Freeze the component class now that it's instantiated at + * least once. + */ + BT_LOGD_STR("Freezing component class."); + bt_component_class_freeze(component->class); + BT_LOGD("Added component to graph: " + "graph-addr=%p, comp-cls-addr=%p, " + "comp-cls-type=%s, name=\"%s\", params-addr=%p, " + "init-method-data-addr=%p, comp-addr=%p", + graph, component_class, bt_component_class_type_string(type), + name, params, init_method_data, component); + + if (user_component) { + /* Move reference to user */ + *user_component = component; + component = NULL; + } + +end: + bt_put(component); + bt_put(params); + return graph_status; +} + +enum bt_graph_status bt_graph_add_component( + struct bt_graph *graph, + struct bt_component_class *component_class, + const char *name, struct bt_value *params, + struct bt_component **component) +{ + return bt_graph_add_component_with_init_method_data(graph, + component_class, name, params, NULL, component); +} diff --git a/lib/graph/sink.c b/lib/graph/sink.c index 9462765f6..455ed4ef1 100644 --- a/lib/graph/sink.c +++ b/lib/graph/sink.c @@ -43,7 +43,7 @@ void bt_component_sink_destroy(struct bt_component *component) BT_HIDDEN struct bt_component *bt_component_sink_create( - struct bt_component_class *class, struct bt_value *params) + struct bt_component_class *class) { struct bt_component_sink *sink = NULL; diff --git a/lib/graph/source.c b/lib/graph/source.c index 758a1b525..b1a12a5d1 100644 --- a/lib/graph/source.c +++ b/lib/graph/source.c @@ -45,7 +45,7 @@ void bt_component_source_destroy(struct bt_component *component) BT_HIDDEN struct bt_component *bt_component_source_create( - struct bt_component_class *class, struct bt_value *params) + struct bt_component_class *class) { struct bt_component_source *source = NULL; diff --git a/tests/lib/test_bt_notification_iterator.c b/tests/lib/test_bt_notification_iterator.c index cbce6b4c9..d6ca1973d 100644 --- a/tests/lib/test_bt_notification_iterator.c +++ b/tests/lib/test_bt_notification_iterator.c @@ -866,7 +866,7 @@ void sink_finalize(struct bt_private_component *private_component) } static -void create_source_sink(struct bt_component **source, +void create_source_sink(struct bt_graph *graph, struct bt_component **source, struct bt_component **sink) { struct bt_component_class *src_comp_class; @@ -887,8 +887,9 @@ void create_source_sink(struct bt_component **source, ret = bt_component_class_source_set_notification_iterator_finalize_method( src_comp_class, src_iter_finalize); assert(ret == 0); - *source = bt_component_create(src_comp_class, "source", NULL); - assert(*source); + ret = bt_graph_add_component(graph, src_comp_class, "source", NULL, + source); + assert(ret == 0); /* Create sink component */ sink_comp_class = bt_component_class_sink_create("sink", sink_consume); @@ -900,7 +901,9 @@ void create_source_sink(struct bt_component **source, ret = bt_component_class_set_port_connected_method(sink_comp_class, sink_port_connected); assert(ret == 0); - *sink = bt_component_create(sink_comp_class, "sink", NULL); + ret = bt_graph_add_component(graph, sink_comp_class, "sink", NULL, + sink); + assert(ret == 0); bt_put(src_comp_class); bt_put(sink_comp_class); @@ -920,9 +923,9 @@ void do_std_test(enum test test, const char *name, clear_test_events(); current_test = test; diag("test: %s", name); - create_source_sink(&src_comp, &sink_comp); graph = bt_graph_create(); assert(graph); + create_source_sink(graph, &src_comp, &sink_comp); /* Connect source to sink */ upstream_port = bt_component_source_get_output_port_by_name(src_comp, "out"); diff --git a/tests/lib/test_graph_topo.c b/tests/lib/test_graph_topo.c index 058393a2b..2efac1444 100644 --- a/tests/lib/test_graph_topo.c +++ b/tests/lib/test_graph_topo.c @@ -39,7 +39,7 @@ #include "tap/tap.h" -#define NR_TESTS 69 +#define NR_TESTS 77 enum event_type { COMP_ACCEPT_PORT_CONNECTION, @@ -588,22 +588,26 @@ void fini_test(void) } static -struct bt_component *create_src(void) +struct bt_component *create_src(struct bt_graph *graph) { - struct bt_component *comp = - bt_component_create(src_comp_class, "src-comp", NULL); + struct bt_component *comp; + int ret; - assert(comp); + ret = bt_graph_add_component(graph, src_comp_class, "src-comp", NULL, + &comp); + assert(ret == 0); return comp; } static -struct bt_component *create_sink(void) +struct bt_component *create_sink(struct bt_graph *graph) { - struct bt_component *comp = - bt_component_create(sink_comp_class, "sink-comp", NULL); + struct bt_component *comp; + int ret; - assert(comp); + ret = bt_graph_add_component(graph, sink_comp_class, "sink-comp", + NULL, &comp); + assert(ret == 0); return comp; } @@ -661,9 +665,10 @@ void test_sink_removes_port_in_port_connected_then_src_removes_disconnected_port prepare_test(TEST_SINK_REMOVES_PORT_IN_CONSUME_THEN_SRC_REMOVES_DISCONNECTED_PORT, "sink removes port in consume, then source removes disconnected port"); - src = create_src(); - sink = create_sink(); graph = create_graph(); + assert(graph); + src = create_src(graph); + sink = create_sink(graph); src_def_port = bt_component_source_get_output_port_by_name(src, "out"); assert(src_def_port); sink_def_port = bt_component_sink_get_input_port_by_name(sink, "in"); @@ -673,8 +678,20 @@ void test_sink_removes_port_in_port_connected_then_src_removes_disconnected_port assert(status == 0); assert(conn); - /* We're supposed to have 5 events so far */ - ok(events->len == 5, "we have the expected number of events (before consume)"); + /* We're supposed to have 7 events so far */ + ok(events->len == 7, "we have the expected number of events (before consume)"); + + /* Source's port added */ + event.type = GRAPH_PORT_ADDED; + event.data.graph_port_added.comp = src; + event.data.graph_port_added.port = src_def_port; + ok(has_event(&event), "got the expected graph's port added event (for source, initial)"); + + /* Sink's port added */ + event.type = GRAPH_PORT_ADDED; + event.data.graph_port_added.comp = sink; + event.data.graph_port_added.port = sink_def_port; + ok(has_event(&event), "got the expected graph's port added event (for sink, initial)"); /* Source's accept port connection */ event.type = COMP_ACCEPT_PORT_CONNECTION; @@ -825,9 +842,10 @@ void test_sink_removes_port_in_port_connected(void) prepare_test(TEST_SINK_REMOVES_PORT_IN_CONSUME, "sink removes port in consume"); - src = create_src(); - sink = create_sink(); graph = create_graph(); + assert(graph); + src = create_src(graph); + sink = create_sink(graph); src_def_port = bt_component_source_get_output_port_by_name(src, "out"); assert(src_def_port); sink_def_port = bt_component_sink_get_input_port_by_name(sink, "in"); @@ -836,8 +854,20 @@ void test_sink_removes_port_in_port_connected(void) &conn); assert(status == 0); - /* We're supposed to have 5 events so far */ - ok(events->len == 5, "we have the expected number of events (before consume)"); + /* We're supposed to have 7 events so far */ + ok(events->len == 7, "we have the expected number of events (before consume)"); + + /* Source's port added */ + event.type = GRAPH_PORT_ADDED; + event.data.graph_port_added.comp = src; + event.data.graph_port_added.port = src_def_port; + ok(has_event(&event), "got the expected graph's port added event (for source, initial)"); + + /* Sink's port added */ + event.type = GRAPH_PORT_ADDED; + event.data.graph_port_added.comp = sink; + event.data.graph_port_added.port = sink_def_port; + ok(has_event(&event), "got the expected graph's port added event (for sink, initial)"); /* Source's accept port connection */ event.type = COMP_ACCEPT_PORT_CONNECTION; @@ -970,9 +1000,10 @@ void test_src_adds_port_in_port_connected(void) prepare_test(TEST_SRC_ADDS_PORT_IN_PORT_CONNECTED, "source adds port in port connected"); - src = create_src(); - sink = create_sink(); graph = create_graph(); + assert(graph); + src = create_src(graph); + sink = create_sink(graph); src_def_port = bt_component_source_get_output_port_by_name(src, "out"); assert(src_def_port); sink_def_port = bt_component_sink_get_input_port_by_name(sink, "in"); @@ -984,8 +1015,20 @@ void test_src_adds_port_in_port_connected(void) "hello"); assert(src_hello_port); - /* We're supposed to have 6 events */ - ok(events->len == 6, "we have the expected number of events"); + /* We're supposed to have 8 events */ + ok(events->len == 8, "we have the expected number of events"); + + /* Source's port added */ + event.type = GRAPH_PORT_ADDED; + event.data.graph_port_added.comp = src; + event.data.graph_port_added.port = src_def_port; + ok(has_event(&event), "got the expected graph's port added event (for source, initial)"); + + /* Sink's port added */ + event.type = GRAPH_PORT_ADDED; + event.data.graph_port_added.comp = sink; + event.data.graph_port_added.port = sink_def_port; + ok(has_event(&event), "got the expected graph's port added event (for sink, initial)"); /* Source's accept port connection */ event.type = COMP_ACCEPT_PORT_CONNECTION; @@ -1077,9 +1120,10 @@ void test_simple(void) size_t graph_ports_connected_pos; prepare_test(TEST_SIMPLE, "simple"); - src = create_src(); - sink = create_sink(); graph = create_graph(); + assert(graph); + src = create_src(graph); + sink = create_sink(graph); src_def_port = bt_component_source_get_output_port_by_name(src, "out"); assert(src_def_port); sink_def_port = bt_component_sink_get_input_port_by_name(sink, "in"); @@ -1088,8 +1132,20 @@ void test_simple(void) &conn); assert(status == 0); - /* We're supposed to have 5 events */ - ok(events->len == 5, "we have the expected number of events"); + /* We're supposed to have 7 events */ + ok(events->len == 7, "we have the expected number of events"); + + /* Source's port added */ + event.type = GRAPH_PORT_ADDED; + event.data.graph_port_added.comp = src; + event.data.graph_port_added.port = src_def_port; + ok(has_event(&event), "got the expected graph's port added event (for source, initial)"); + + /* Sink's port added */ + event.type = GRAPH_PORT_ADDED; + event.data.graph_port_added.comp = sink; + event.data.graph_port_added.port = sink_def_port; + ok(has_event(&event), "got the expected graph's port added event (for sink, initial)"); /* Source's accept port connection */ event.type = COMP_ACCEPT_PORT_CONNECTION; diff --git a/tests/lib/test_plugin.c b/tests/lib/test_plugin.c index d4390dcbe..cec0933e0 100644 --- a/tests/lib/test_plugin.c +++ b/tests/lib/test_plugin.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -148,6 +149,7 @@ static void test_sfs(const char *plugin_dir) struct bt_value *results; struct bt_value *object; struct bt_value *res_params; + struct bt_graph *graph; const char *object_str; int ret; @@ -218,20 +220,35 @@ static void test_sfs(const char *plugin_dir) diag("> putting the plugin object here"); BT_PUT(plugin); - sink_component = bt_component_create(sink_comp_class, NULL, NULL); - ok(sink_component, "bt_component_create() still works after the plugin object is destroyed"); + graph = bt_graph_create(); + assert(graph); + ret = bt_graph_add_component(graph, sink_comp_class, "the-sink", NULL, + &sink_component); + ok(ret == 0 && sink_component, + "bt_graph_add_component() still works after the plugin object is destroyed"); BT_PUT(sink_component); BT_PUT(source_comp_class); - sink_component = bt_component_create(sink_comp_class, NULL, NULL); - ok(sink_component, "bt_component_create() still works after the source component class object is destroyed"); + bt_put(graph); + graph = bt_graph_create(); + assert(graph); + ret = bt_graph_add_component(graph, sink_comp_class, "the-sink", NULL, + &sink_component); + ok(ret == 0 && sink_component, + "bt_graph_add_component() still works after the source component class object is destroyed"); BT_PUT(sink_component); BT_PUT(filter_comp_class); - sink_component = bt_component_create(sink_comp_class, NULL, NULL); - ok(sink_component, "bt_component_create() still works after the filter component class object is destroyed"); + bt_put(graph); + graph = bt_graph_create(); + assert(graph); + ret = bt_graph_add_component(graph, sink_comp_class, "the-sink", NULL, + &sink_component); + ok(ret == 0 && sink_component, + "bt_graph_add_component() still works after the filter component class object is destroyed"); BT_PUT(sink_comp_class); BT_PUT(sink_component); free(sfs_path); + bt_put(graph); bt_put(plugin_set); bt_put(object); bt_put(res_params); diff --git a/tests/plugins/test-utils-muxer.c b/tests/plugins/test-utils-muxer.c index 6600a72e8..76edfd76d 100644 --- a/tests/plugins/test-utils-muxer.c +++ b/tests/plugins/test-utils-muxer.c @@ -912,7 +912,8 @@ void sink_finalize(struct bt_private_component *private_component) } static -void create_source_muxer_sink(struct bt_component **source, +void create_source_muxer_sink(struct bt_graph *graph, + struct bt_component **source, struct bt_component **muxer, struct bt_component **sink) { @@ -935,15 +936,15 @@ void create_source_muxer_sink(struct bt_component **source, ret = bt_component_class_source_set_notification_iterator_finalize_method( src_comp_class, src_iter_finalize); assert(ret == 0); - *source = bt_component_create(src_comp_class, "source", NULL); - assert(*source); + ret = bt_graph_add_component(graph, src_comp_class, "source", NULL, source); + assert(ret == 0); /* Create muxer component */ muxer_comp_class = bt_plugin_find_component_class("utils", "muxer", BT_COMPONENT_CLASS_TYPE_FILTER); assert(muxer_comp_class); - *muxer = bt_component_create(muxer_comp_class, "muxer", NULL); - assert(*muxer); + ret = bt_graph_add_component(graph, muxer_comp_class, "muxer", NULL, muxer); + assert(ret == 0); /* Create sink component */ sink_comp_class = bt_component_class_sink_create("sink", sink_consume); @@ -955,7 +956,8 @@ void create_source_muxer_sink(struct bt_component **source, ret = bt_component_class_set_port_connected_method(sink_comp_class, sink_port_connected); assert(ret == 0); - *sink = bt_component_create(sink_comp_class, "sink", NULL); + ret = bt_graph_add_component(graph, sink_comp_class, "sink", NULL, sink); + assert(ret == 0); bt_put(src_comp_class); bt_put(muxer_comp_class); @@ -980,9 +982,9 @@ void do_std_test(enum test test, const char *name, clear_test_events(); current_test = test; diag("test: %s", name); - create_source_muxer_sink(&src_comp, &muxer_comp, &sink_comp); graph = bt_graph_create(); assert(graph); + create_source_muxer_sink(graph, &src_comp, &muxer_comp, &sink_comp); /* Connect source output ports to muxer input ports */ if (with_upstream) { @@ -1454,9 +1456,9 @@ void test_single_end_then_multiple_full(void) clear_test_events(); current_test = TEST_SINGLE_END_THEN_MULTIPLE_FULL; diag("test: single end then multiple full"); - create_source_muxer_sink(&src_comp, &muxer_comp, &sink_comp); graph = bt_graph_create(); assert(graph); + create_source_muxer_sink(graph, &src_comp, &muxer_comp, &sink_comp); graph_listener_data.graph = graph; graph_listener_data.source = src_comp; graph_listener_data.muxer = muxer_comp; @@ -1582,9 +1584,9 @@ void test_single_again_end_then_multiple_full(void) clear_test_events(); current_test = TEST_SINGLE_AGAIN_END_THEN_MULTIPLE_FULL; diag("test: single again then end then multiple full"); - create_source_muxer_sink(&src_comp, &muxer_comp, &sink_comp); graph = bt_graph_create(); assert(graph); + create_source_muxer_sink(graph, &src_comp, &muxer_comp, &sink_comp); graph_listener_data.graph = graph; graph_listener_data.source = src_comp; graph_listener_data.muxer = muxer_comp;