From 0d8b4d8edb6b11ddd7f4e6adc77b9390a0db0b20 Mon Sep 17 00:00:00 2001 From: Philippe Proulx Date: Wed, 5 Apr 2017 16:11:36 -0400 Subject: [PATCH] Add "port connected" component class method MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit What used to be "accept port connection" is now split in "accept port connection" and "port connected". The latter confirms that the two ports are connected after they both accepted the connection. Thus in the "accept port connection" method, the ports are not connected yet: this is not where the component can create a notification iterator because the connection object does not exist. Signed-off-by: Philippe Proulx Signed-off-by: Jérémie Galarneau --- .../graph/component-class-internal.h | 1 + include/babeltrace/graph/component-class.h | 9 ++ include/babeltrace/graph/component-internal.h | 4 + include/babeltrace/plugin/plugin-dev.h | 81 +++++++++++- lib/graph/component-class.c | 17 +++ lib/graph/component.c | 15 +++ lib/graph/graph.c | 115 ++++-------------- lib/plugin/plugin-so.c | 15 +++ plugins/text/plugin.c | 4 +- plugins/text/pretty/pretty.c | 13 +- plugins/text/pretty/pretty.h | 3 +- plugins/utils/dummy/dummy.c | 15 ++- plugins/utils/dummy/dummy.h | 5 +- plugins/utils/plugin.c | 3 +- plugins/writer/writer.c | 16 ++- plugins/writer/writer.h | 1 + 16 files changed, 202 insertions(+), 115 deletions(-) diff --git a/include/babeltrace/graph/component-class-internal.h b/include/babeltrace/graph/component-class-internal.h index 68a8e0c1..364299c6 100644 --- a/include/babeltrace/graph/component-class-internal.h +++ b/include/babeltrace/graph/component-class-internal.h @@ -59,6 +59,7 @@ struct bt_component_class { bt_component_class_finalize_method finalize; bt_component_class_query_method query; bt_component_class_accept_port_connection_method accept_port_connection; + bt_component_class_port_connected_method port_connected; bt_component_class_port_disconnected_method port_disconnected; } methods; /* Array of struct bt_component_class_destroy_listener */ diff --git a/include/babeltrace/graph/component-class.h b/include/babeltrace/graph/component-class.h index cf031cfe..c2d59da6 100644 --- a/include/babeltrace/graph/component-class.h +++ b/include/babeltrace/graph/component-class.h @@ -88,6 +88,11 @@ typedef enum bt_component_status (*bt_component_class_accept_port_connection_met struct bt_private_port *self_private_port, struct bt_port *other_port); +typedef void (*bt_component_class_port_connected_method)( + struct bt_private_component *private_component, + struct bt_private_port *self_private_port, + struct bt_port *other_port); + typedef void (*bt_component_class_port_disconnected_method)( struct bt_private_component *private_component, struct bt_private_port *private_port); @@ -104,6 +109,10 @@ extern int bt_component_class_set_accept_port_connection_method( struct bt_component_class *component_class, bt_component_class_accept_port_connection_method accept_port_connection_method); +extern int bt_component_class_set_port_connected_method( + struct bt_component_class *component_class, + bt_component_class_port_connected_method port_connected_method); + extern int bt_component_class_set_port_disconnected_method( struct bt_component_class *component_class, bt_component_class_port_disconnected_method port_disconnected_method); diff --git a/include/babeltrace/graph/component-internal.h b/include/babeltrace/graph/component-internal.h index 4c50ffb9..1e7b547a 100644 --- a/include/babeltrace/graph/component-internal.h +++ b/include/babeltrace/graph/component-internal.h @@ -82,6 +82,10 @@ enum bt_component_status bt_component_accept_port_connection( struct bt_component *component, struct bt_port *self_port, struct bt_port *other_port); +BT_HIDDEN +void bt_component_port_connected(struct bt_component *comp, + struct bt_port *self_port, struct bt_port *other_port); + BT_HIDDEN void bt_component_port_disconnected(struct bt_component *comp, struct bt_port *port); diff --git a/include/babeltrace/plugin/plugin-dev.h b/include/babeltrace/plugin/plugin-dev.h index 4a0dadd2..c50a9e3e 100644 --- a/include/babeltrace/plugin/plugin-dev.h +++ b/include/babeltrace/plugin/plugin-dev.h @@ -168,10 +168,11 @@ enum __bt_plugin_component_class_descriptor_attribute_type { BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_FINALIZE_METHOD = 3, BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_QUERY_METHOD = 4, BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_ACCEPT_PORT_CONNECTION_METHOD = 5, - BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_PORT_DISCONNECTED_METHOD = 6, - BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_NOTIF_ITER_INIT_METHOD = 7, - BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_NOTIF_ITER_FINALIZE_METHOD = 8, - BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_NOTIF_ITER_SEEK_TIME_METHOD = 9, + BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_PORT_CONNECTED_METHOD = 7, + BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_PORT_DISCONNECTED_METHOD = 8, + BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_NOTIF_ITER_INIT_METHOD = 9, + BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_NOTIF_ITER_FINALIZE_METHOD = 10, + BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_NOTIF_ITER_SEEK_TIME_METHOD = 11, }; /* Component class attribute (internal use) */ @@ -208,6 +209,9 @@ struct __bt_plugin_component_class_descriptor_attribute { /* BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_ACCEPT_PORT_CONNECTION_METHOD */ bt_component_class_accept_port_connection_method accept_port_connection_method; + /* BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_PORT_CONNECTED_METHOD */ + bt_component_class_port_connected_method port_connected_method; + /* BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_PORT_DISCONNECTED_METHOD */ bt_component_class_port_disconnected_method port_disconnected_method; @@ -651,6 +655,42 @@ struct __bt_plugin_component_class_descriptor_attribute { #define BT_PLUGIN_SINK_COMPONENT_CLASS_ACCEPT_PORT_CONNECTION_METHOD_WITH_ID(_id, _comp_class_id, _x) \ __BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE(accept_port_connection_method, BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_ACCEPT_PORT_CONNECTION_METHOD, _id, _comp_class_id, sink, _x) +/* + * Defines a port connected method attribute attached to a specific + * source component class descriptor. + * + * _id: Plugin descriptor ID (C identifier). + * _comp_class_id: Component class descriptor ID (C identifier). + * _x: Port connected method + * (bt_component_class_port_connected_method). + */ +#define BT_PLUGIN_SOURCE_COMPONENT_CLASS_PORT_CONNECTED_METHOD_WITH_ID(_id, _comp_class_id, _x) \ + __BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE(port_connected_method, BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_PORT_CONNECTED_METHOD, _id, _comp_class_id, source, _x) + +/* + * Defines a port connected method attribute attached to a specific + * filter component class descriptor. + * + * _id: Plugin descriptor ID (C identifier). + * _comp_class_id: Component class descriptor ID (C identifier). + * _x: Port connected method + * (bt_component_class_port_connected_method). + */ +#define BT_PLUGIN_FILTER_COMPONENT_CLASS_PORT_CONNECTED_METHOD_WITH_ID(_id, _comp_class_id, _x) \ + __BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE(port_connected_method, BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_PORT_CONNECTED_METHOD, _id, _comp_class_id, filter, _x) + +/* + * Defines a port connected method attribute attached to a specific + * sink component class descriptor. + * + * _id: Plugin descriptor ID (C identifier). + * _comp_class_id: Component class descriptor ID (C identifier). + * _x: Port connected method + * (bt_component_class_port_connected_method). + */ +#define BT_PLUGIN_SINK_COMPONENT_CLASS_PORT_CONNECTED_METHOD_WITH_ID(_id, _comp_class_id, _x) \ + __BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE(port_connected_method, BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_PORT_CONNECTED_METHOD, _id, _comp_class_id, sink, _x) + /* * Defines a port disconnected method attribute attached to a specific * source component class descriptor. @@ -1047,6 +1087,39 @@ struct __bt_plugin_component_class_descriptor_attribute { #define BT_PLUGIN_SINK_COMPONENT_CLASS_ACCEPT_PORT_CONNECTION_METHOD(_name, _x) \ BT_PLUGIN_SINK_COMPONENT_CLASS_ACCEPT_PORT_CONNECTION_METHOD_WITH_ID(auto, _name, _x) +/* + * Defines a port connected method attribute attached to a source + * component class descriptor which is attached to the automatic plugin + * descriptor. + * + * _name: Component class name (C identifier). + * _x: Port connected (bt_component_class_port_connected_method). + */ +#define BT_PLUGIN_SOURCE_COMPONENT_CLASS_PORT_CONNECTED_METHOD(_name, _x) \ + BT_PLUGIN_SOURCE_COMPONENT_CLASS_PORT_CONNECTED_METHOD_WITH_ID(auto, _name, _x) + +/* + * Defines a port connected method attribute attached to a filter + * component class descriptor which is attached to the automatic plugin + * descriptor. + * + * _name: Component class name (C identifier). + * _x: Port connected (bt_component_class_port_connected_method). + */ +#define BT_PLUGIN_FILTER_COMPONENT_CLASS_PORT_CONNECTED_METHOD(_name, _x) \ + BT_PLUGIN_FILTER_COMPONENT_CLASS_PORT_CONNECTED_METHOD_WITH_ID(auto, _name, _x) + +/* + * Defines a port connected method attribute attached to a sink + * component class descriptor which is attached to the automatic plugin + * descriptor. + * + * _name: Component class name (C identifier). + * _x: Port connected (bt_component_class_port_connected_method). + */ +#define BT_PLUGIN_SINK_COMPONENT_CLASS_PORT_CONNECTED_METHOD(_name, _x) \ + BT_PLUGIN_SINK_COMPONENT_CLASS_PORT_CONNECTED_METHOD_WITH_ID(auto, _name, _x) + /* * Defines a port disconnected method attribute attached to a source * component class descriptor which is attached to the automatic plugin diff --git a/lib/graph/component-class.c b/lib/graph/component-class.c index 4585b1f3..28aa04c5 100644 --- a/lib/graph/component-class.c +++ b/lib/graph/component-class.c @@ -256,6 +256,23 @@ end: return ret; } +int bt_component_class_set_port_connected_method( + struct bt_component_class *component_class, + bt_component_class_port_connected_method method) +{ + int ret = 0; + + if (!component_class || component_class->frozen || !method) { + ret = -1; + goto end; + } + + component_class->methods.port_connected = method; + +end: + return ret; +} + int bt_component_class_set_port_disconnected_method( struct bt_component_class *component_class, bt_component_class_port_disconnected_method method) diff --git a/lib/graph/component.c b/lib/graph/component.c index 9b996f62..26d77605 100644 --- a/lib/graph/component.c +++ b/lib/graph/component.c @@ -553,6 +553,21 @@ enum bt_component_status bt_component_accept_port_connection( return status; } +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); + + if (comp->class->methods.port_connected) { + comp->class->methods.port_connected( + bt_private_component_from_component(comp), + bt_private_port_from_port(self_port), other_port); + } +} + BT_HIDDEN void bt_component_port_disconnected(struct bt_component *comp, struct bt_port *port) diff --git a/lib/graph/graph.c b/lib/graph/graph.c index c861fa3c..e397d354 100644 --- a/lib/graph/graph.c +++ b/lib/graph/graph.c @@ -154,12 +154,9 @@ struct bt_connection *bt_graph_connect_ports(struct bt_graph *graph, struct bt_graph *downstream_graph = NULL; struct bt_component *upstream_component = NULL; struct bt_component *downstream_component = NULL; - struct bt_connection *existing_conn = NULL; enum bt_component_status component_status; bool upstream_was_already_in_graph; bool downstream_was_already_in_graph; - int components_to_remove = 0; - int i; if (!graph || !upstream_port || !downstream_port) { goto end; @@ -174,16 +171,12 @@ struct bt_connection *bt_graph_connect_ports(struct bt_graph *graph, } /* Ensure that both ports are currently unconnected. */ - existing_conn = bt_port_get_connection(upstream_port); - bt_put(existing_conn); - if (existing_conn) { + if (bt_port_is_connected(upstream_port)) { fprintf(stderr, "Upstream port is already connected\n"); goto end; } - existing_conn = bt_port_get_connection(downstream_port); - bt_put(existing_conn); - if (existing_conn) { + if (bt_port_is_connected(downstream_port)) { fprintf(stderr, "Downstream port is already connected\n"); goto end; } @@ -218,6 +211,22 @@ struct bt_connection *bt_graph_connect_ports(struct bt_graph *graph, } 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 + * port by the other port before we continue. + */ + component_status = bt_component_accept_port_connection( + upstream_component, upstream_port, downstream_port); + if (component_status != BT_COMPONENT_STATUS_OK) { + goto error; + } + component_status = bt_component_accept_port_connection( + downstream_component, downstream_port, upstream_port); + if (component_status != BT_COMPONENT_STATUS_OK) { + goto error; + } + connection = bt_connection_create(graph, upstream_port, downstream_port); if (!connection) { @@ -245,30 +254,21 @@ struct bt_connection *bt_graph_connect_ports(struct bt_graph *graph, } /* - * The graph is now the parent of these components which garantees their - * existence for the duration of the graph's lifetime. + * The graph is now the parent of these components which + * garantees their existence for the duration of the graph's + * lifetime. */ /* - * The components and connection are added to the graph before - * invoking the `accept_port_connection` method in order to make - * them visible to the components during the method's - * invocation. + * Notify both components that their port is connected. */ - component_status = bt_component_accept_port_connection( - upstream_component, upstream_port, downstream_port); - if (component_status != BT_COMPONENT_STATUS_OK) { - goto error_rollback; - } - component_status = bt_component_accept_port_connection( - downstream_component, downstream_port, upstream_port); - if (component_status != BT_COMPONENT_STATUS_OK) { - goto error_rollback; - } + bt_component_port_connected(upstream_component, upstream_port, + downstream_port); + bt_component_port_connected(downstream_component, downstream_port, + upstream_port); /* - * Both components accepted the connection. Notify the graph's - * creator that both ports are connected. + * Notify the graph's creator that both ports are connected. */ bt_graph_notify_ports_connected(graph, upstream_port, downstream_port); @@ -278,68 +278,7 @@ end: bt_put(upstream_component); bt_put(downstream_component); return connection; -error_rollback: - /* - * Remove newly-added components from the graph, being careful - * not to remove a component that was already present in the graph - * and is connected to other components. - */ - components_to_remove += upstream_was_already_in_graph ? 0 : 1; - components_to_remove += downstream_was_already_in_graph ? 0 : 1; - if (!downstream_was_already_in_graph) { - if (bt_component_get_class_type(downstream_component) == - BT_COMPONENT_CLASS_TYPE_SINK) { - g_queue_pop_tail(graph->sinks_to_consume); - } - } - /* Remove newly created connection. */ - g_ptr_array_set_size(graph->connections, - graph->connections->len - 1); - - /* - * Remove newly added components. - * - * Note that this is a tricky situation. The graph, being the parent - * of the components, does not hold a reference to them. Normally, - * components are destroyed right away when the graph is released since - * the graph, being their parent, bounds their lifetime - * (see doc/ref-counting.md). - * - * In this particular case, we must take a number of steps: - * 1) unset the components' parent to rollback the initial state of - * the components being connected. - * Note that the reference taken by the component on its graph is - * released by the set_parent call. - * 2) set the pointer in the components array to NULL so that the - * destruction function called on the array's resize in invoked on - * NULL (no effect), - * - * NOTE: Point #1 assumes that *something* holds a reference to both - * components being connected. The fact that a reference is being - * held to a component means that it must hold a reference to its - * parent to prevent the parent from being destroyed (again, refer - * to doc/red-counting.md). This reference to a component is - * most likely being held *transitively* by the caller which holds - * a reference to both ports (a port has its component as a - * parent). - * - * This assumes that a graph is not connecting components by - * itself while not holding a reference to the ports/components - * being connected (i.e. "cheating" by using internal APIs). - */ - for (i = 0; i < components_to_remove; i++) { - struct bt_component *component = g_ptr_array_index( - graph->components, graph->components->len - 1); - - bt_component_set_graph(component, NULL); - g_ptr_array_index(graph->components, - graph->components->len - 1) = NULL; - g_ptr_array_set_size(graph->components, - graph->components->len - 1); - } - /* NOTE: Resizing the ptr_arrays invokes the destruction of the elements. */ - goto end; error: BT_PUT(upstream_component); BT_PUT(downstream_component); diff --git a/lib/plugin/plugin-so.c b/lib/plugin/plugin-so.c index 2e528ea0..77c29c13 100644 --- a/lib/plugin/plugin-so.c +++ b/lib/plugin/plugin-so.c @@ -254,6 +254,7 @@ enum bt_plugin_status bt_plugin_so_init( bt_component_class_finalize_method finalize_method; bt_component_class_query_method query_method; bt_component_class_accept_port_connection_method accept_port_connection_method; + bt_component_class_port_connected_method port_connected_method; bt_component_class_port_disconnected_method port_disconnected_method; struct bt_component_class_iterator_methods iterator_methods; }; @@ -387,6 +388,10 @@ enum bt_plugin_status bt_plugin_so_init( cc_full_descr->accept_port_connection_method = cur_cc_descr_attr->value.accept_port_connection_method; break; + case BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_PORT_CONNECTED_METHOD: + cc_full_descr->port_connected_method = + cur_cc_descr_attr->value.port_connected_method; + break; case BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_PORT_DISCONNECTED_METHOD: cc_full_descr->port_disconnected_method = cur_cc_descr_attr->value.port_disconnected_method; @@ -524,6 +529,16 @@ enum bt_plugin_status bt_plugin_so_init( } } + if (cc_full_descr->port_connected_method) { + ret = bt_component_class_set_port_connected_method( + comp_class, cc_full_descr->port_connected_method); + if (ret) { + status = BT_PLUGIN_STATUS_ERROR; + BT_PUT(comp_class); + goto end; + } + } + if (cc_full_descr->port_disconnected_method) { ret = bt_component_class_set_port_disconnected_method( comp_class, cc_full_descr->port_disconnected_method); diff --git a/plugins/text/plugin.c b/plugins/text/plugin.c index a7691019..1449e757 100644 --- a/plugins/text/plugin.c +++ b/plugins/text/plugin.c @@ -32,7 +32,7 @@ BT_PLUGIN_LICENSE("MIT"); BT_PLUGIN_SINK_COMPONENT_CLASS(pretty, pretty_consume); BT_PLUGIN_SINK_COMPONENT_CLASS_INIT_METHOD(pretty, pretty_init); BT_PLUGIN_SINK_COMPONENT_CLASS_FINALIZE_METHOD(pretty, pretty_finalize); -BT_PLUGIN_SINK_COMPONENT_CLASS_ACCEPT_PORT_CONNECTION_METHOD(pretty, - pretty_accept_port_connection); +BT_PLUGIN_SINK_COMPONENT_CLASS_PORT_CONNECTED_METHOD(pretty, + pretty_port_connected); BT_PLUGIN_SINK_COMPONENT_CLASS_DESCRIPTION(pretty, "Pretty-printing text output (`text` format of Babeltrace 1)"); diff --git a/plugins/text/pretty/pretty.c b/plugins/text/pretty/pretty.c index 48a71472..14f8560c 100644 --- a/plugins/text/pretty/pretty.c +++ b/plugins/text/pretty/pretty.c @@ -168,12 +168,11 @@ end: } BT_HIDDEN -enum bt_component_status pretty_accept_port_connection( +void pretty_port_connected( struct bt_private_component *component, struct bt_private_port *self_port, struct bt_port *other_port) { - enum bt_component_status ret = BT_COMPONENT_STATUS_OK; struct bt_private_connection *connection; struct pretty_component *pretty; @@ -186,11 +185,10 @@ enum bt_component_status pretty_accept_port_connection( bt_private_connection_create_notification_iterator(connection); if (!pretty->input_iterator) { - ret = BT_COMPONENT_STATUS_ERROR; + pretty->error = true; } bt_put(connection); - return ret; } BT_HIDDEN @@ -203,9 +201,14 @@ enum bt_component_status pretty_consume(struct bt_private_component *component) bt_private_component_get_user_data(component); enum bt_notification_iterator_status it_ret; - it = pretty->input_iterator; + if (unlikely(pretty->error)) { + ret = BT_COMPONENT_STATUS_ERROR; + goto end; + } + it = pretty->input_iterator; it_ret = bt_notification_iterator_next(it); + switch (it_ret) { case BT_NOTIFICATION_ITERATOR_STATUS_ERROR: ret = BT_COMPONENT_STATUS_ERROR; diff --git a/plugins/text/pretty/pretty.h b/plugins/text/pretty/pretty.h index 1eaf20c4..9caa5778 100644 --- a/plugins/text/pretty/pretty.h +++ b/plugins/text/pretty/pretty.h @@ -88,6 +88,7 @@ struct pretty_component { GString *string; struct bt_value *plugin_opt_map; /* Temporary parameter map. */ bool use_colors; + bool error; uint64_t last_cycles_timestamp; uint64_t delta_cycles; @@ -118,7 +119,7 @@ BT_HIDDEN enum bt_component_status pretty_consume(struct bt_private_component *component); BT_HIDDEN -enum bt_component_status pretty_accept_port_connection( +void pretty_port_connected( struct bt_private_component *component, struct bt_private_port *self_port, struct bt_port *other_port); diff --git a/plugins/utils/dummy/dummy.c b/plugins/utils/dummy/dummy.c index df4b5a3b..01782859 100644 --- a/plugins/utils/dummy/dummy.c +++ b/plugins/utils/dummy/dummy.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include "dummy.h" @@ -81,33 +82,30 @@ error: return ret; } -enum bt_component_status dummy_accept_port_connection( +void dummy_port_connected( struct bt_private_component *component, struct bt_private_port *self_port, struct bt_port *other_port) { - enum bt_component_status ret = BT_COMPONENT_STATUS_OK; struct dummy *dummy; struct bt_notification_iterator *iterator; struct bt_private_connection *connection; dummy = bt_private_component_get_user_data(component); assert(dummy); - connection = bt_private_port_get_private_connection(self_port); assert(connection); - iterator = bt_private_connection_create_notification_iterator( connection); if (!iterator) { - ret = BT_COMPONENT_STATUS_ERROR; + dummy->error = true; goto end; } g_ptr_array_add(dummy->iterators, iterator); + end: bt_put(connection); - return ret; } enum bt_component_status dummy_consume(struct bt_private_component *component) @@ -120,6 +118,11 @@ enum bt_component_status dummy_consume(struct bt_private_component *component) dummy = bt_private_component_get_user_data(component); assert(dummy); + if (unlikely(dummy->error)) { + ret = BT_COMPONENT_STATUS_ERROR; + goto end; + } + /* Consume one notification from each iterator. */ for (i = 0; i < dummy->iterators->len; i++) { struct bt_notification_iterator *it; diff --git a/plugins/utils/dummy/dummy.h b/plugins/utils/dummy/dummy.h index 77e25111..fd11c5db 100644 --- a/plugins/utils/dummy/dummy.h +++ b/plugins/utils/dummy/dummy.h @@ -27,16 +27,17 @@ #include #include #include +#include struct dummy { GPtrArray *iterators; + bool error; }; enum bt_component_status dummy_init(struct bt_private_component *component, struct bt_value *params, void *init_method_data); void dummy_finalize(struct bt_private_component *component); -enum bt_component_status dummy_accept_port_connection( - struct bt_private_component *component, +void dummy_port_connected(struct bt_private_component *component, struct bt_private_port *self_port, struct bt_port *other_port); enum bt_component_status dummy_consume(struct bt_private_component *component); diff --git a/plugins/utils/plugin.c b/plugins/utils/plugin.c index f621cc3e..6dd7c852 100644 --- a/plugins/utils/plugin.c +++ b/plugins/utils/plugin.c @@ -34,7 +34,8 @@ BT_PLUGIN_LICENSE("MIT"); BT_PLUGIN_SINK_COMPONENT_CLASS(dummy, dummy_consume); BT_PLUGIN_SINK_COMPONENT_CLASS_INIT_METHOD(dummy, dummy_init); BT_PLUGIN_SINK_COMPONENT_CLASS_FINALIZE_METHOD(dummy, dummy_finalize); -BT_PLUGIN_SINK_COMPONENT_CLASS_ACCEPT_PORT_CONNECTION_METHOD(dummy, dummy_accept_port_connection); +BT_PLUGIN_SINK_COMPONENT_CLASS_PORT_CONNECTED_METHOD(dummy, + dummy_port_connected); BT_PLUGIN_SINK_COMPONENT_CLASS_DESCRIPTION(dummy, "Dummy sink component class: does absolutely nothing!"); diff --git a/plugins/writer/writer.c b/plugins/writer/writer.c index 5dbd5d59..d50af13b 100644 --- a/plugins/writer/writer.c +++ b/plugins/writer/writer.c @@ -185,12 +185,11 @@ end: } static -enum bt_component_status writer_component_accept_port_connection( +void writer_component_port_connected( struct bt_private_component *component, struct bt_private_port *self_port, struct bt_port *other_port) { - enum bt_component_status ret = BT_COMPONENT_STATUS_OK; struct bt_private_connection *connection; struct writer_component *writer; @@ -203,10 +202,10 @@ enum bt_component_status writer_component_accept_port_connection( bt_private_connection_create_notification_iterator(connection); if (!writer->input_iterator) { - ret = BT_COMPONENT_STATUS_ERROR; + writer->error = true; } + bt_put(connection); - return ret; } static @@ -221,6 +220,11 @@ enum bt_component_status run(struct bt_private_component *component) it = writer_component->input_iterator; assert(it); + if (unlikely(writer_component->error)) { + ret = BT_COMPONENT_STATUS_ERROR; + goto end; + } + if (likely(writer_component->processed_first_event)) { enum bt_notification_iterator_status it_ret; @@ -308,7 +312,7 @@ BT_PLUGIN_AUTHOR("Jérémie Galarneau"); BT_PLUGIN_LICENSE("MIT"); BT_PLUGIN_SINK_COMPONENT_CLASS(writer, run); BT_PLUGIN_SINK_COMPONENT_CLASS_INIT_METHOD(writer, writer_component_init); -BT_PLUGIN_SINK_COMPONENT_CLASS_ACCEPT_PORT_CONNECTION_METHOD(writer, - writer_component_accept_port_connection); +BT_PLUGIN_SINK_COMPONENT_CLASS_PORT_CONNECTED_METHOD(writer, + writer_component_port_connected); BT_PLUGIN_SINK_COMPONENT_CLASS_FINALIZE_METHOD(writer, finalize_writer_component); BT_PLUGIN_SINK_COMPONENT_CLASS_DESCRIPTION(writer, "Formats CTF-IR to CTF."); diff --git a/plugins/writer/writer.h b/plugins/writer/writer.h index f5c0d108..6f6b8a49 100644 --- a/plugins/writer/writer.h +++ b/plugins/writer/writer.h @@ -46,6 +46,7 @@ struct writer_component { FILE *err; struct bt_notification_iterator *input_iterator; bool processed_first_event; + bool error; }; BT_HIDDEN -- 2.34.1