From 5badd463e184894a3bfd5b8db257efc6f92c6374 Mon Sep 17 00:00:00 2001 From: Philippe Proulx Date: Thu, 21 Feb 2019 17:12:11 -0500 Subject: [PATCH] lib: add sink component class's "graph is configured" method All filter component classes implement the same logic currently to support their instance being connected input first or output first. Before this patch, if a filter component was connected to a sink component, the sink component's "input port connected" method was called and this is where the sink component had to create an input port message iterator. This made the filter message iterator initialize, but it was possible that the filter's input ports were not connected yet. To support this connection order, the filter message iterator had to add itself to a list of iterators within the component's private data, and upstream iterators had to be initialized when the filter component's "input port connected" method was called. Also, when the filter message iterator was finalized, it had to remove itself from the component's list. This strategy worked, but it was cumbersome and did lead to duplicated code amongst different filters. This patch does the following: * It makes the graph have two phases: configuration and post-configuration. The configuration phase is when you create and connect components. The post-configuration is as soon as you call bt_graph_run(), bt_graph_consume(), or bt_port_output_message_iterator_create(). * It makes it incorrect (validated in developer mode) to create an input port message iterator during the graph's configuration phase. In other words, an "input port connected" method cannot call bt_self_component_port_input_message_iterator_create() anymore. * It adds an optional sink component class's "graph is configured" method. This method is considered to be called when the graph is configured (post-configuration phase): it is called at the beginning of bt_graph_run() or bt_graph_consume() when it was not previously called. This is where a sink can call bt_self_component_port_input_message_iterator_create() now. This leads to a chain of message iterator initialization which all occur during the post-configuration phase. This guarantees to the initialization methods that ports are connected, and that disconnected ports will never be connected. This is not a big change for sink component classes, if any: for the `sink.text.pretty`, `sink.utils.counter`, and `sink.utils.dummy` component classes, the "input port connected" method is simply replaced with the "graph is configured" method. This is however a big change for filter component classes. For example, the `flt.utils.muxer` component class is much simpler as of this patch: it simply creates all its upstream message iterators in its message iterator initialization method, and hundreds of lines of codes are removed. Checking that the graph is configured at the beginning of bt_graph_consume() could potentially have a performance impact, but I did not measure this. If it's the case, then we would need a dedicated graph function, for example bt_graph_confirm_configuration(), to call the "graph is configured" methods once before calling bt_graph_consume() in a loop. Signed-off-by: Philippe Proulx --- .../graph/component-class-internal.h | 1 + .../babeltrace/graph/component-class-sink.h | 9 + .../graph/component-sink-internal.h | 1 + include/babeltrace/graph/graph-internal.h | 117 ++++++- include/babeltrace/plugin/plugin-dev.h | 40 ++- lib/graph/component-class.c | 54 +-- lib/graph/component.c | 3 +- lib/graph/graph.c | 24 +- lib/graph/iterator.c | 38 ++- lib/lib-logging.c | 6 +- lib/plugin/plugin-so.c | 23 ++ plugins/text/plugin.c | 4 +- plugins/text/pretty/pretty.c | 15 +- plugins/text/pretty/pretty.h | 6 +- plugins/utils/counter/counter.c | 12 +- plugins/utils/counter/counter.h | 6 +- plugins/utils/dummy/dummy.c | 12 +- plugins/utils/dummy/dummy.h | 6 +- plugins/utils/muxer/muxer.c | 311 +++--------------- plugins/utils/plugin.c | 8 +- 20 files changed, 326 insertions(+), 370 deletions(-) diff --git a/include/babeltrace/graph/component-class-internal.h b/include/babeltrace/graph/component-class-internal.h index 953fa91a..b6e71881 100644 --- a/include/babeltrace/graph/component-class-internal.h +++ b/include/babeltrace/graph/component-class-internal.h @@ -88,6 +88,7 @@ struct bt_component_class_sink { bt_component_class_sink_query_method query; bt_component_class_sink_accept_input_port_connection_method accept_input_port_connection; bt_component_class_sink_input_port_connected_method input_port_connected; + bt_component_class_sink_graph_is_configured_method graph_is_configured; bt_component_class_sink_consume_method consume; } methods; }; diff --git a/include/babeltrace/graph/component-class-sink.h b/include/babeltrace/graph/component-class-sink.h index 003f549f..601974b9 100644 --- a/include/babeltrace/graph/component-class-sink.h +++ b/include/babeltrace/graph/component-class-sink.h @@ -72,6 +72,10 @@ typedef bt_self_component_status bt_self_component_port_input *self_port, const bt_port_output *other_port); +typedef bt_self_component_status +(*bt_component_class_sink_graph_is_configured_method)( + bt_self_component_sink *self_component); + typedef bt_self_component_status (*bt_component_class_sink_consume_method)( bt_self_component_sink *self_component); @@ -105,6 +109,11 @@ bt_component_class_sink_set_input_port_connected_method( bt_component_class_sink *comp_class, bt_component_class_sink_input_port_connected_method method); +extern bt_component_class_status +bt_component_class_sink_set_graph_is_configured_method( + bt_component_class_sink *comp_class, + bt_component_class_sink_graph_is_configured_method method); + extern bt_component_class_status bt_component_class_sink_set_query_method( bt_component_class_sink *comp_class, bt_component_class_sink_query_method method); diff --git a/include/babeltrace/graph/component-sink-internal.h b/include/babeltrace/graph/component-sink-internal.h index 74e5af92..164b9635 100644 --- a/include/babeltrace/graph/component-sink-internal.h +++ b/include/babeltrace/graph/component-sink-internal.h @@ -32,6 +32,7 @@ struct bt_component_sink { struct bt_component parent; + bool graph_is_configured_method_called; }; BT_HIDDEN diff --git a/include/babeltrace/graph/graph-internal.h b/include/babeltrace/graph/graph-internal.h index dc1399a8..97289cf0 100644 --- a/include/babeltrace/graph/graph-internal.h +++ b/include/babeltrace/graph/graph-internal.h @@ -27,6 +27,8 @@ #include #include #include +#include +#include #include #include #include @@ -37,6 +39,12 @@ struct bt_component; struct bt_port; +enum bt_graph_configuration_state { + BT_GRAPH_CONFIGURATION_STATE_CONFIGURING, + BT_GRAPH_CONFIGURATION_STATE_PARTIALLY_CONFIGURED, + BT_GRAPH_CONFIGURATION_STATE_CONFIGURED, +}; + struct bt_graph { /** * A component graph contains components and point-to-point connection @@ -73,11 +81,7 @@ struct bt_graph { */ bool can_consume; - /* - * True if the graph is configured, that is, components are - * added and connected. - */ - bool is_configured; + enum bt_graph_configuration_state config_state; struct { GArray *source_output_port_added; @@ -129,19 +133,6 @@ void _bt_graph_set_can_consume(struct bt_graph *graph, bool can_consume) # define bt_graph_set_can_consume(_graph, _can_consume) #endif -static inline -void _bt_graph_set_is_configured(struct bt_graph *graph, bool is_configured) -{ - BT_ASSERT(graph); - graph->is_configured = is_configured; -} - -#ifdef BT_DEV_MODE -# define bt_graph_set_is_configured _bt_graph_set_is_configured -#else -# define bt_graph_set_is_configured(_graph, _is_configured) -#endif - BT_HIDDEN enum bt_graph_status bt_graph_consume_sink_no_check(struct bt_graph *graph, struct bt_component_sink *sink); @@ -198,4 +189,94 @@ const char *bt_graph_status_string(enum bt_graph_status status) } } +static inline +const char *bt_graph_configuration_state_string( + enum bt_graph_configuration_state state) +{ + switch (state) { + case BT_GRAPH_CONFIGURATION_STATE_CONFIGURING: + return "BT_GRAPH_CONFIGURATION_STATE_CONFIGURING"; + case BT_GRAPH_CONFIGURATION_STATE_PARTIALLY_CONFIGURED: + return "BT_GRAPH_CONFIGURATION_STATE_PARTIALLY_CONFIGURED"; + case BT_GRAPH_CONFIGURATION_STATE_CONFIGURED: + return "BT_GRAPH_CONFIGURATION_STATE_CONFIGURED"; + default: + return "(unknown)"; + } +} + +static inline +enum bt_graph_status bt_graph_configure(struct bt_graph *graph) +{ + enum bt_graph_status status = BT_GRAPH_STATUS_OK; + uint64_t i; + + if (likely(graph->config_state == + BT_GRAPH_CONFIGURATION_STATE_CONFIGURED)) { + goto end; + } + + graph->config_state = BT_GRAPH_CONFIGURATION_STATE_PARTIALLY_CONFIGURED; + + for (i = 0; i < graph->components->len; i++) { + struct bt_component *comp = graph->components->pdata[i]; + struct bt_component_sink *comp_sink = (void *) comp; + struct bt_component_class_sink *comp_cls_sink = + (void *) comp->class; + + if (comp->class->type != BT_COMPONENT_CLASS_TYPE_SINK) { + continue; + } + + if (comp_sink->graph_is_configured_method_called) { + continue; + } + + if (comp_cls_sink->methods.graph_is_configured) { + enum bt_self_component_status comp_status; + +#ifdef BT_LIB_LOGD + BT_LIB_LOGD("Calling user's \"graph is configured\" method: " + "%![graph-]+g, %![comp-]+c", + graph, comp); +#endif + + comp_status = comp_cls_sink->methods.graph_is_configured( + (void *) comp_sink); + +#ifdef BT_LIB_LOGD + BT_LIB_LOGD("User method returned: status=%s", + bt_self_component_status_string(comp_status)); +#endif + +#ifdef BT_ASSERT_PRE + BT_ASSERT_PRE(comp_status == BT_SELF_COMPONENT_STATUS_OK || + comp_status == BT_SELF_COMPONENT_STATUS_ERROR || + comp_status == BT_SELF_COMPONENT_STATUS_NOMEM, + "Unexpected returned status: status=%s", + bt_self_component_status_string(comp_status)); +#endif + + if (comp_status != BT_SELF_COMPONENT_STATUS_OK) { +#ifdef BT_LIB_LOGW + BT_LIB_LOGW("User's \"graph is configured\" method failed: " + "%![comp-]+c, status=%s", + comp, + bt_self_component_status_string( + comp_status)); +#endif + + goto end; + } + } + + comp_sink->graph_is_configured_method_called = true; + } + + graph->config_state = BT_GRAPH_CONFIGURATION_STATE_CONFIGURED; + +end: + return status; +} + #endif /* BABELTRACE_GRAPH_GRAPH_INTERNAL_H */ diff --git a/include/babeltrace/plugin/plugin-dev.h b/include/babeltrace/plugin/plugin-dev.h index 1be7aa93..66b79ded 100644 --- a/include/babeltrace/plugin/plugin-dev.h +++ b/include/babeltrace/plugin/plugin-dev.h @@ -184,12 +184,13 @@ enum __bt_plugin_component_class_descriptor_attribute_type { BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_ACCEPT_OUTPUT_PORT_CONNECTION_METHOD = 6, BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_INPUT_PORT_CONNECTED_METHOD = 7, BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_OUTPUT_PORT_CONNECTED_METHOD = 8, - BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_MSG_ITER_INIT_METHOD = 9, - BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_MSG_ITER_FINALIZE_METHOD = 10, - BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_MSG_ITER_SEEK_NS_FROM_ORIGIN_METHOD = 11, - BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_MSG_ITER_SEEK_BEGINNING_METHOD = 12, - BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_MSG_ITER_CAN_SEEK_NS_FROM_ORIGIN_METHOD = 13, - BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_MSG_ITER_CAN_SEEK_BEGINNING_METHOD = 14, + BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_GRAPH_IS_CONFIGURED_METHOD = 9, + BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_MSG_ITER_INIT_METHOD = 10, + BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_MSG_ITER_FINALIZE_METHOD = 11, + BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_MSG_ITER_SEEK_NS_FROM_ORIGIN_METHOD = 12, + BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_MSG_ITER_SEEK_BEGINNING_METHOD = 13, + BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_MSG_ITER_CAN_SEEK_NS_FROM_ORIGIN_METHOD = 14, + BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_MSG_ITER_CAN_SEEK_BEGINNING_METHOD = 15, }; /* Component class attribute (internal use) */ @@ -245,6 +246,9 @@ struct __bt_plugin_component_class_descriptor_attribute { bt_component_class_source_output_port_connected_method source_output_port_connected_method; bt_component_class_filter_output_port_connected_method filter_output_port_connected_method; + /* BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_GRAPH_IS_CONFIGURED_METHOD */ + bt_component_class_sink_graph_is_configured_method sink_graph_is_configured_method; + /* BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_MSG_ITER_INIT_METHOD */ bt_component_class_source_message_iterator_init_method source_msg_iter_init_method; bt_component_class_filter_message_iterator_init_method filter_msg_iter_init_method; @@ -868,6 +872,18 @@ struct __bt_plugin_component_class_descriptor_attribute const * const *__bt_get_ #define BT_PLUGIN_FILTER_COMPONENT_CLASS_OUTPUT_PORT_CONNECTED_METHOD_WITH_ID(_id, _comp_class_id, _x) \ __BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE(filter_output_port_connected_method, BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_OUTPUT_PORT_CONNECTED_METHOD, _id, _comp_class_id, filter, _x) +/* + * Defines a "graph is configured" 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: "Graph is configured" method + * (bt_component_class_sink_graph_is_configured_method). + */ +#define BT_PLUGIN_SINK_COMPONENT_CLASS_GRAPH_IS_CONFIGURED_METHOD_WITH_ID(_id, _comp_class_id, _x) \ + __BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE(sink_graph_is_configured_method, BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_GRAPH_IS_CONFIGURED_METHOD, _id, _comp_class_id, sink, _x) + /* * Defines an iterator initialization method attribute attached to a * specific source component class descriptor. @@ -1356,6 +1372,18 @@ struct __bt_plugin_component_class_descriptor_attribute const * const *__bt_get_ #define BT_PLUGIN_FILTER_COMPONENT_CLASS_OUTPUT_PORT_CONNECTED_METHOD(_name, _x) \ BT_PLUGIN_FILTER_COMPONENT_CLASS_OUTPUT_PORT_CONNECTED_METHOD_WITH_ID(auto, _name, _x) +/* + * Defines a "graph is configured" method attribute attached to + * a sink component class descriptor which is attached to the automatic + * plugin descriptor. + * + * _name: Component class name (C identifier). + * _x: "Graph is configured" method + * (bt_component_class_sink_graph_is_configured_method). + */ +#define BT_PLUGIN_SINK_COMPONENT_CLASS_GRAPH_IS_CONFIGURED_METHOD(_name, _x) \ + BT_PLUGIN_SINK_COMPONENT_CLASS_GRAPH_IS_CONFIGURED_METHOD_WITH_ID(auto, _name, _x) + /* * Defines an iterator initialization method attribute attached to a * source component class descriptor which is attached to the automatic diff --git a/lib/graph/component-class.c b/lib/graph/component-class.c index 7f90720e..314cc04e 100644 --- a/lib/graph/component-class.c +++ b/lib/graph/component-class.c @@ -245,7 +245,7 @@ end: return (void *) sink_class; } -extern enum bt_component_class_status +enum bt_component_class_status bt_component_class_source_set_init_method( struct bt_component_class_source *comp_cls, bt_component_class_source_init_method method) @@ -259,7 +259,7 @@ bt_component_class_source_set_init_method( return BT_COMPONENT_CLASS_STATUS_OK; } -extern enum bt_component_class_status +enum bt_component_class_status bt_component_class_filter_set_init_method( struct bt_component_class_filter *comp_cls, bt_component_class_filter_init_method method) @@ -273,7 +273,7 @@ bt_component_class_filter_set_init_method( return BT_COMPONENT_CLASS_STATUS_OK; } -extern enum bt_component_class_status +enum bt_component_class_status bt_component_class_sink_set_init_method( struct bt_component_class_sink *comp_cls, bt_component_class_sink_init_method method) @@ -287,7 +287,7 @@ bt_component_class_sink_set_init_method( return BT_COMPONENT_CLASS_STATUS_OK; } -extern enum bt_component_class_status +enum bt_component_class_status bt_component_class_source_set_finalize_method( struct bt_component_class_source *comp_cls, bt_component_class_source_finalize_method method) @@ -301,7 +301,7 @@ bt_component_class_source_set_finalize_method( return BT_COMPONENT_CLASS_STATUS_OK; } -extern enum bt_component_class_status +enum bt_component_class_status bt_component_class_filter_set_finalize_method( struct bt_component_class_filter *comp_cls, bt_component_class_filter_finalize_method method) @@ -315,7 +315,7 @@ bt_component_class_filter_set_finalize_method( return BT_COMPONENT_CLASS_STATUS_OK; } -extern enum bt_component_class_status +enum bt_component_class_status bt_component_class_sink_set_finalize_method( struct bt_component_class_sink *comp_cls, bt_component_class_sink_finalize_method method) @@ -329,7 +329,7 @@ bt_component_class_sink_set_finalize_method( return BT_COMPONENT_CLASS_STATUS_OK; } -extern enum bt_component_class_status +enum bt_component_class_status bt_component_class_source_set_query_method( struct bt_component_class_source *comp_cls, bt_component_class_source_query_method method) @@ -343,7 +343,7 @@ bt_component_class_source_set_query_method( return BT_COMPONENT_CLASS_STATUS_OK; } -extern enum bt_component_class_status +enum bt_component_class_status bt_component_class_filter_set_query_method( struct bt_component_class_filter *comp_cls, bt_component_class_filter_query_method method) @@ -357,7 +357,7 @@ bt_component_class_filter_set_query_method( return BT_COMPONENT_CLASS_STATUS_OK; } -extern enum bt_component_class_status +enum bt_component_class_status bt_component_class_sink_set_query_method( struct bt_component_class_sink *comp_cls, bt_component_class_sink_query_method method) @@ -371,7 +371,7 @@ bt_component_class_sink_set_query_method( return BT_COMPONENT_CLASS_STATUS_OK; } -extern enum bt_component_class_status +enum bt_component_class_status bt_component_class_filter_set_accept_input_port_connection_method( struct bt_component_class_filter *comp_cls, bt_component_class_filter_accept_input_port_connection_method method) @@ -385,7 +385,7 @@ bt_component_class_filter_set_accept_input_port_connection_method( return BT_COMPONENT_CLASS_STATUS_OK; } -extern enum bt_component_class_status +enum bt_component_class_status bt_component_class_sink_set_accept_input_port_connection_method( struct bt_component_class_sink *comp_cls, bt_component_class_sink_accept_input_port_connection_method method) @@ -399,7 +399,7 @@ bt_component_class_sink_set_accept_input_port_connection_method( return BT_COMPONENT_CLASS_STATUS_OK; } -extern enum bt_component_class_status +enum bt_component_class_status bt_component_class_source_set_accept_output_port_connection_method( struct bt_component_class_source *comp_cls, bt_component_class_source_accept_output_port_connection_method method) @@ -413,7 +413,7 @@ bt_component_class_source_set_accept_output_port_connection_method( return BT_COMPONENT_CLASS_STATUS_OK; } -extern enum bt_component_class_status +enum bt_component_class_status bt_component_class_filter_set_accept_output_port_connection_method( struct bt_component_class_filter *comp_cls, bt_component_class_filter_accept_output_port_connection_method method) @@ -427,7 +427,7 @@ bt_component_class_filter_set_accept_output_port_connection_method( return BT_COMPONENT_CLASS_STATUS_OK; } -extern enum bt_component_class_status +enum bt_component_class_status bt_component_class_filter_set_input_port_connected_method( struct bt_component_class_filter *comp_cls, bt_component_class_filter_input_port_connected_method method) @@ -441,7 +441,7 @@ bt_component_class_filter_set_input_port_connected_method( return BT_COMPONENT_CLASS_STATUS_OK; } -extern enum bt_component_class_status +enum bt_component_class_status bt_component_class_sink_set_input_port_connected_method( struct bt_component_class_sink *comp_cls, bt_component_class_sink_input_port_connected_method method) @@ -455,7 +455,7 @@ bt_component_class_sink_set_input_port_connected_method( return BT_COMPONENT_CLASS_STATUS_OK; } -extern enum bt_component_class_status +enum bt_component_class_status bt_component_class_source_set_output_port_connected_method( struct bt_component_class_source *comp_cls, bt_component_class_source_output_port_connected_method method) @@ -469,7 +469,7 @@ bt_component_class_source_set_output_port_connected_method( return BT_COMPONENT_CLASS_STATUS_OK; } -extern enum bt_component_class_status +enum bt_component_class_status bt_component_class_filter_set_output_port_connected_method( struct bt_component_class_filter *comp_cls, bt_component_class_filter_output_port_connected_method method) @@ -483,6 +483,20 @@ bt_component_class_filter_set_output_port_connected_method( return BT_COMPONENT_CLASS_STATUS_OK; } +enum bt_component_class_status +bt_component_class_sink_set_graph_is_configured_method( + struct bt_component_class_sink *comp_cls, + bt_component_class_sink_graph_is_configured_method method) +{ + BT_ASSERT_PRE_NON_NULL(comp_cls, "Component class"); + BT_ASSERT_PRE_NON_NULL(method, "Method"); + BT_ASSERT_PRE_COMP_CLS_HOT(comp_cls); + comp_cls->methods.graph_is_configured = method; + BT_LIB_LOGV("Set sink component class's \"graph is configured\" method" + ": %!+C", comp_cls); + return BT_COMPONENT_CLASS_STATUS_OK; +} + int bt_component_class_source_set_message_iterator_init_method( struct bt_component_class_source *comp_cls, bt_component_class_source_message_iterator_init_method method) @@ -496,7 +510,7 @@ int bt_component_class_source_set_message_iterator_init_method( return BT_COMPONENT_CLASS_STATUS_OK; } -extern enum bt_component_class_status +enum bt_component_class_status bt_component_class_filter_set_message_iterator_init_method( struct bt_component_class_filter *comp_cls, bt_component_class_filter_message_iterator_init_method method) @@ -510,7 +524,7 @@ bt_component_class_filter_set_message_iterator_init_method( return BT_COMPONENT_CLASS_STATUS_OK; } -extern enum bt_component_class_status +enum bt_component_class_status bt_component_class_source_set_message_iterator_finalize_method( struct bt_component_class_source *comp_cls, bt_component_class_source_message_iterator_finalize_method method) @@ -524,7 +538,7 @@ bt_component_class_source_set_message_iterator_finalize_method( return BT_COMPONENT_CLASS_STATUS_OK; } -extern enum bt_component_class_status +enum bt_component_class_status bt_component_class_filter_set_message_iterator_finalize_method( struct bt_component_class_filter *comp_cls, bt_component_class_filter_message_iterator_finalize_method method) diff --git a/lib/graph/component.c b/lib/graph/component.c index 48454d64..53c9cd6d 100644 --- a/lib/graph/component.c +++ b/lib/graph/component.c @@ -204,7 +204,8 @@ struct bt_port *add_port( BT_ASSERT_PRE(graph && !bt_graph_is_canceled(graph), "Component's graph is canceled: %![comp-]+c, %![graph-]+g", component, graph); - BT_ASSERT_PRE(!graph->is_configured, + BT_ASSERT_PRE( + graph->config_state == BT_GRAPH_CONFIGURATION_STATE_CONFIGURING, "Component's graph is already configured: " "%![comp-]+c, %![graph-]+g", component, graph); diff --git a/lib/graph/graph.c b/lib/graph/graph.c index d5fc0b6b..49933d54 100644 --- a/lib/graph/graph.c +++ b/lib/graph/graph.c @@ -406,7 +406,8 @@ enum bt_graph_status bt_graph_connect_ports( BT_ASSERT_PRE_NON_NULL(upstream_port, "Upstream port"); BT_ASSERT_PRE_NON_NULL(downstream_port, "Downstream port port"); BT_ASSERT_PRE(!graph->canceled, "Graph is canceled: %!+g", graph); - BT_ASSERT_PRE(!graph->is_configured, + BT_ASSERT_PRE( + graph->config_state == BT_GRAPH_CONFIGURATION_STATE_CONFIGURING, "Graph is already configured: %!+g", graph); BT_ASSERT_PRE(!bt_port_is_connected(upstream_port), "Upstream port is already connected: %!+p", upstream_port); @@ -680,22 +681,34 @@ enum bt_graph_status bt_graph_consume(struct bt_graph *graph) BT_ASSERT_PRE(graph->can_consume, "Cannot consume graph in its current state: %!+g", graph); bt_graph_set_can_consume(graph, false); - bt_graph_set_is_configured(graph, true); + status = bt_graph_configure(graph); + if (status) { + /* bt_graph_configure() logs errors */ + goto end; + } + status = consume_no_check(graph); bt_graph_set_can_consume(graph, true); + +end: return status; } enum bt_graph_status bt_graph_run(struct bt_graph *graph) { - enum bt_graph_status status = BT_GRAPH_STATUS_OK; + enum bt_graph_status status; BT_ASSERT_PRE_NON_NULL(graph, "Graph"); BT_ASSERT_PRE(!graph->canceled, "Graph is canceled: %!+g", graph); BT_ASSERT_PRE(graph->can_consume, "Cannot consume graph in its current state: %!+g", graph); bt_graph_set_can_consume(graph, false); - bt_graph_set_is_configured(graph, true); + status = bt_graph_configure(graph); + if (status) { + /* bt_graph_configure() logs errors */ + goto end; + } + BT_LIB_LOGV("Running graph: %!+g", graph); do { @@ -1234,7 +1247,8 @@ enum bt_graph_status add_component_with_init_method_data( BT_ASSERT_PRE_NON_NULL(graph, "Graph"); BT_ASSERT_PRE_NON_NULL(name, "Name"); BT_ASSERT_PRE(!graph->canceled, "Graph is canceled: %!+g", graph); - BT_ASSERT_PRE(!graph->is_configured, + BT_ASSERT_PRE( + graph->config_state == BT_GRAPH_CONFIGURATION_STATE_CONFIGURING, "Graph is already configured: %!+g", graph); BT_ASSERT_PRE(!component_name_exists(graph, name), "Duplicate component name: %!+g, name=\"%s\"", graph, name); diff --git a/lib/graph/iterator.c b/lib/graph/iterator.c index ddfe417c..c97ec94d 100644 --- a/lib/graph/iterator.c +++ b/lib/graph/iterator.c @@ -440,6 +440,11 @@ bt_self_component_port_input_message_iterator_create( BT_ASSERT(upstream_port); upstream_comp = bt_port_borrow_component_inline(upstream_port); BT_ASSERT(upstream_comp); + BT_ASSERT_PRE( + bt_component_borrow_graph(upstream_comp)->config_state != + BT_GRAPH_CONFIGURATION_STATE_CONFIGURING, + "Graph is not configured: %!+g", + bt_component_borrow_graph(upstream_comp)); upstream_comp_cls = upstream_comp->class; BT_ASSERT(upstream_comp->class->type == BT_COMPONENT_CLASS_TYPE_SOURCE || @@ -574,7 +579,9 @@ bt_self_component_port_input_message_iterator_next( "message iterator is in the wrong state: %!+i", iterator); BT_ASSERT(iterator->upstream_component); BT_ASSERT(iterator->upstream_component->class); - BT_ASSERT_PRE(bt_component_borrow_graph(iterator->upstream_component)->is_configured, + BT_ASSERT_PRE( + bt_component_borrow_graph(iterator->upstream_component)->config_state != + BT_GRAPH_CONFIGURATION_STATE_CONFIGURING, "Graph is not configured: %!+g", bt_component_borrow_graph(iterator->upstream_component)); BT_LIB_LOGD("Getting next self component input port " @@ -646,13 +653,6 @@ enum bt_message_iterator_status bt_port_output_message_iterator_next( BT_ASSERT_PRE_NON_NULL(count_to_user, "Message count (output)"); BT_LIB_LOGD("Getting next output port message iterator's messages: " "%!+i", iterator); - - /* - * As soon as the user calls this function, we mark the graph as - * being definitely configured. - */ - bt_graph_set_is_configured(iterator->graph, true); - graph_status = bt_graph_consume_sink_no_check(iterator->graph, iterator->colander); switch (graph_status) { @@ -825,6 +825,12 @@ bt_port_output_message_iterator_create(struct bt_graph *graph, * member. */ bt_graph_set_can_consume(iterator->graph, false); + + /* + * Also set the graph as being configured: it has no active sink + * anyway, so we don't need to call bt_graph_configure(). + */ + graph->config_state = BT_GRAPH_CONFIGURATION_STATE_CONFIGURED; goto end; error: @@ -866,7 +872,9 @@ bt_bool bt_self_component_port_input_message_iterator_can_seek_ns_from_origin( BT_ASSERT_PRE_NON_NULL(iterator, "Message iterator"); BT_ASSERT_PRE_ITER_HAS_STATE_TO_SEEK(iterator); - BT_ASSERT_PRE(bt_component_borrow_graph(iterator->upstream_component)->is_configured, + BT_ASSERT_PRE( + bt_component_borrow_graph(iterator->upstream_component)->config_state != + BT_GRAPH_CONFIGURATION_STATE_CONFIGURING, "Graph is not configured: %!+g", bt_component_borrow_graph(iterator->upstream_component)); @@ -895,7 +903,9 @@ bt_bool bt_self_component_port_input_message_iterator_can_seek_beginning( BT_ASSERT_PRE_NON_NULL(iterator, "Message iterator"); BT_ASSERT_PRE_ITER_HAS_STATE_TO_SEEK(iterator); - BT_ASSERT_PRE(bt_component_borrow_graph(iterator->upstream_component)->is_configured, + BT_ASSERT_PRE( + bt_component_borrow_graph(iterator->upstream_component)->config_state != + BT_GRAPH_CONFIGURATION_STATE_CONFIGURING, "Graph is not configured: %!+g", bt_component_borrow_graph(iterator->upstream_component)); @@ -949,7 +959,9 @@ bt_self_component_port_input_message_iterator_seek_beginning( BT_ASSERT_PRE_NON_NULL(iterator, "Message iterator"); BT_ASSERT_PRE_ITER_HAS_STATE_TO_SEEK(iterator); - BT_ASSERT_PRE(bt_component_borrow_graph(iterator->upstream_component)->is_configured, + BT_ASSERT_PRE( + bt_component_borrow_graph(iterator->upstream_component)->config_state != + BT_GRAPH_CONFIGURATION_STATE_CONFIGURING, "Graph is not configured: %!+g", bt_component_borrow_graph(iterator->upstream_component)); BT_ASSERT_PRE( @@ -1284,7 +1296,9 @@ bt_self_component_port_input_message_iterator_seek_ns_from_origin( BT_ASSERT_PRE_NON_NULL(iterator, "Message iterator"); BT_ASSERT_PRE_ITER_HAS_STATE_TO_SEEK(iterator); - BT_ASSERT_PRE(bt_component_borrow_graph(iterator->upstream_component)->is_configured, + BT_ASSERT_PRE( + bt_component_borrow_graph(iterator->upstream_component)->config_state != + BT_GRAPH_CONFIGURATION_STATE_CONFIGURING, "Graph is not configured: %!+g", bt_component_borrow_graph(iterator->upstream_component)); BT_ASSERT_PRE( diff --git a/lib/lib-logging.c b/lib/lib-logging.c index a1b9a7ea..3fd96dd1 100644 --- a/lib/lib-logging.c +++ b/lib/lib-logging.c @@ -1094,7 +1094,11 @@ static inline void format_graph(char **buf_ch, bool extended, { char tmp_prefix[64]; - BUF_APPEND(", %sis-canceled=%d", PRFIELD(graph->canceled)); + BUF_APPEND(", %sis-canceled=%d, %scan-consume=%d, " + "%sconfig-state=%s", + PRFIELD(graph->canceled), + PRFIELD(graph->can_consume), + PRFIELD(bt_graph_configuration_state_string(graph->config_state))); if (!extended) { return; diff --git a/lib/plugin/plugin-so.c b/lib/plugin/plugin-so.c index ed8d5e29..ac0ec75b 100644 --- a/lib/plugin/plugin-so.c +++ b/lib/plugin/plugin-so.c @@ -327,6 +327,7 @@ enum bt_plugin_status bt_plugin_so_init( bt_component_class_sink_query_method query; bt_component_class_sink_accept_input_port_connection_method accept_input_port_connection; bt_component_class_sink_input_port_connected_method input_port_connected; + bt_component_class_sink_graph_is_configured_method graph_is_configured; } sink; } methods; }; @@ -596,6 +597,16 @@ enum bt_plugin_status bt_plugin_so_init( abort(); } break; + case BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_GRAPH_IS_CONFIGURED_METHOD: + switch (cc_type) { + case BT_COMPONENT_CLASS_TYPE_SINK: + cc_full_descr->methods.sink.graph_is_configured = + cur_cc_descr_attr->value.sink_graph_is_configured_method; + break; + default: + abort(); + } + break; case BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_MSG_ITER_INIT_METHOD: switch (cc_type) { case BT_COMPONENT_CLASS_TYPE_SOURCE: @@ -1173,6 +1184,18 @@ enum bt_plugin_status bt_plugin_so_init( } } + if (cc_full_descr->methods.sink.graph_is_configured) { + ret = bt_component_class_sink_set_graph_is_configured_method( + sink_comp_class, + cc_full_descr->methods.sink.graph_is_configured); + if (ret) { + BT_LOGE_STR("Cannot set sink component class's \"graph is configured\" method."); + status = BT_PLUGIN_STATUS_ERROR; + BT_OBJECT_PUT_REF_AND_RESET(sink_comp_class); + goto end; + } + } + break; default: abort(); diff --git a/plugins/text/plugin.c b/plugins/text/plugin.c index 55507de5..bdd2789c 100644 --- a/plugins/text/plugin.c +++ b/plugins/text/plugin.c @@ -37,8 +37,8 @@ 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_INPUT_PORT_CONNECTED_METHOD(pretty, - pretty_port_connected); +BT_PLUGIN_SINK_COMPONENT_CLASS_GRAPH_IS_CONFIGURED_METHOD(pretty, + pretty_graph_is_configured); BT_PLUGIN_SINK_COMPONENT_CLASS_DESCRIPTION(pretty, "Pretty-print messages (`text` format of Babeltrace 1)."); diff --git a/plugins/text/pretty/pretty.c b/plugins/text/pretty/pretty.c index d83b30c1..1b5729ab 100644 --- a/plugins/text/pretty/pretty.c +++ b/plugins/text/pretty/pretty.c @@ -62,6 +62,9 @@ const char *plugin_options[] = { "field-callsite", }; +static +const char * const in_port_name = "in"; + static void destroy_pretty_data(struct pretty_component *pretty) { @@ -152,10 +155,8 @@ bt_self_component_status handle_message( } BT_HIDDEN -bt_self_component_status pretty_port_connected( - bt_self_component_sink *comp, - bt_self_component_port_input *self_port, - const bt_port_output *other_port) +bt_self_component_status pretty_graph_is_configured( + bt_self_component_sink *comp) { bt_self_component_status status = BT_SELF_COMPONENT_STATUS_OK; struct pretty_component *pretty; @@ -165,7 +166,8 @@ bt_self_component_status pretty_port_connected( BT_ASSERT(pretty); BT_ASSERT(!pretty->iterator); pretty->iterator = bt_self_component_port_input_message_iterator_create( - self_port); + bt_self_component_sink_borrow_input_port_by_name(comp, + in_port_name)); if (!pretty->iterator) { status = BT_SELF_COMPONENT_STATUS_NOMEM; } @@ -650,7 +652,8 @@ bt_self_component_status pretty_init( goto end; } - ret = bt_self_component_sink_add_input_port(comp, "in", NULL, NULL); + ret = bt_self_component_sink_add_input_port(comp, in_port_name, + NULL, NULL); if (ret != BT_SELF_COMPONENT_STATUS_OK) { goto end; } diff --git a/plugins/text/pretty/pretty.h b/plugins/text/pretty/pretty.h index d9e03c90..e1027277 100644 --- a/plugins/text/pretty/pretty.h +++ b/plugins/text/pretty/pretty.h @@ -114,10 +114,8 @@ bt_self_component_status pretty_consume( bt_self_component_sink *component); BT_HIDDEN -bt_self_component_status pretty_port_connected( - bt_self_component_sink *component, - bt_self_component_port_input *self_port, - const bt_port_output *other_port); +bt_self_component_status pretty_graph_is_configured( + bt_self_component_sink *component); BT_HIDDEN void pretty_finalize(bt_self_component_sink *component); diff --git a/plugins/utils/counter/counter.c b/plugins/utils/counter/counter.c index fa75b6ae..ec0a8dba 100644 --- a/plugins/utils/counter/counter.c +++ b/plugins/utils/counter/counter.c @@ -39,6 +39,9 @@ } \ } while (0) +static +const char * const in_port_name = "in"; + static uint64_t get_total_count(struct counter *counter) { @@ -176,10 +179,8 @@ end: } BT_HIDDEN -bt_self_component_status counter_port_connected( - bt_self_component_sink *comp, - bt_self_component_port_input *self_port, - const bt_port_output *other_port) +bt_self_component_status counter_graph_is_configured( + bt_self_component_sink *comp) { bt_self_component_status status = BT_SELF_COMPONENT_STATUS_OK; struct counter *counter; @@ -189,7 +190,8 @@ bt_self_component_status counter_port_connected( bt_self_component_sink_as_self_component(comp)); BT_ASSERT(counter); iterator = bt_self_component_port_input_message_iterator_create( - self_port); + bt_self_component_sink_borrow_input_port_by_name(comp, + in_port_name)); if (!iterator) { status = BT_SELF_COMPONENT_STATUS_NOMEM; goto end; diff --git a/plugins/utils/counter/counter.h b/plugins/utils/counter/counter.h index b3a93b6f..e4cbdde7 100644 --- a/plugins/utils/counter/counter.h +++ b/plugins/utils/counter/counter.h @@ -54,10 +54,8 @@ BT_HIDDEN void counter_finalize(bt_self_component_sink *component); BT_HIDDEN -bt_self_component_status counter_port_connected( - bt_self_component_sink *component, - bt_self_component_port_input *self_port, - const bt_port_output *other_port); +bt_self_component_status counter_graph_is_configured( + bt_self_component_sink *component); BT_HIDDEN bt_self_component_status counter_consume(bt_self_component_sink *component); diff --git a/plugins/utils/dummy/dummy.c b/plugins/utils/dummy/dummy.c index e0c44c5b..61cdfe02 100644 --- a/plugins/utils/dummy/dummy.c +++ b/plugins/utils/dummy/dummy.c @@ -26,6 +26,9 @@ #include #include "dummy.h" +static +const char * const in_port_name = "in"; + void destroy_private_dummy_data(struct dummy *dummy) { bt_self_component_port_input_message_iterator_put_ref(dummy->msg_iter); @@ -77,10 +80,8 @@ end: } BT_HIDDEN -bt_self_component_status dummy_port_connected( - bt_self_component_sink *comp, - bt_self_component_port_input *self_port, - const bt_port_output *other_port) +bt_self_component_status dummy_graph_is_configured( + bt_self_component_sink *comp) { bt_self_component_status status = BT_SELF_COMPONENT_STATUS_OK; struct dummy *dummy; @@ -90,7 +91,8 @@ bt_self_component_status dummy_port_connected( bt_self_component_sink_as_self_component(comp)); BT_ASSERT(dummy); iterator = bt_self_component_port_input_message_iterator_create( - self_port); + bt_self_component_sink_borrow_input_port_by_name(comp, + in_port_name)); if (!iterator) { status = BT_SELF_COMPONENT_STATUS_NOMEM; goto end; diff --git a/plugins/utils/dummy/dummy.h b/plugins/utils/dummy/dummy.h index ed2ddfdb..5df1a2de 100644 --- a/plugins/utils/dummy/dummy.h +++ b/plugins/utils/dummy/dummy.h @@ -41,10 +41,8 @@ BT_HIDDEN void dummy_finalize(bt_self_component_sink *component); BT_HIDDEN -bt_self_component_status dummy_port_connected( - bt_self_component_sink *comp, - bt_self_component_port_input *self_port, - const bt_port_output *other_port); +bt_self_component_status dummy_graph_is_configured( + bt_self_component_sink *comp); BT_HIDDEN bt_self_component_status dummy_consume( diff --git a/plugins/utils/muxer/muxer.c b/plugins/utils/muxer/muxer.c index a6a71b7a..aa5cbb23 100644 --- a/plugins/utils/muxer/muxer.c +++ b/plugins/utils/muxer/muxer.c @@ -44,13 +44,6 @@ #define ASSUME_ABSOLUTE_CLOCK_CLASSES_PARAM_NAME "assume-absolute-clock-classes" struct muxer_comp { - /* - * Array of struct - * bt_self_message_iterator * - * (weak refs) - */ - GPtrArray *muxer_msg_iters; - /* Weak ref */ bt_self_component_filter *self_comp; @@ -86,17 +79,6 @@ struct muxer_msg_iter { */ GPtrArray *muxer_upstream_msg_iters; - /* - * List of "recently" connected input ports (weak) to - * handle by this muxer message iterator. - * muxer_port_connected() adds entries to this list, and the - * entries are removed when a message iterator is created - * on the port's connection and put into - * muxer_upstream_msg_iters above by - * muxer_msg_iter_handle_newly_connected_ports(). - */ - GList *newly_connected_self_ports; - /* Last time returned in a message */ int64_t last_returned_ts_ns; @@ -173,7 +155,7 @@ end: } static -bt_self_component_status ensure_available_input_port( +bt_self_component_status add_available_input_port( bt_self_component_filter *self_comp) { struct muxer_comp *muxer_comp = bt_self_component_get_data( @@ -182,11 +164,6 @@ bt_self_component_status ensure_available_input_port( GString *port_name = NULL; BT_ASSERT(muxer_comp); - - if (muxer_comp->available_input_ports >= 1) { - goto end; - } - port_name = g_string_new("in"); if (!port_name) { BT_LOGE_STR("Failed to allocate a GString."); @@ -210,6 +187,7 @@ bt_self_component_status ensure_available_input_port( BT_LOGD("Added one input port to muxer component: " "port-name=\"%s\", comp-addr=%p", port_name->str, self_comp); + end: if (port_name) { g_string_free(port_name, TRUE); @@ -233,15 +211,6 @@ void destroy_muxer_comp(struct muxer_comp *muxer_comp) return; } - BT_LOGD("Destroying muxer component: muxer-comp-addr=%p, " - "muxer-msg-iter-count=%u", muxer_comp, - muxer_comp->muxer_msg_iters ? - muxer_comp->muxer_msg_iters->len : 0); - - if (muxer_comp->muxer_msg_iters) { - g_ptr_array_free(muxer_comp->muxer_msg_iters, TRUE); - } - g_free(muxer_comp); } @@ -331,8 +300,6 @@ BT_HIDDEN bt_self_component_status muxer_init( bt_self_component_filter *self_comp, const bt_value *params, void *init_data) - - { int ret; bt_self_component_status status = BT_SELF_COMPONENT_STATUS_OK; @@ -354,17 +321,11 @@ bt_self_component_status muxer_init( goto error; } - muxer_comp->muxer_msg_iters = g_ptr_array_new(); - if (!muxer_comp->muxer_msg_iters) { - BT_LOGE_STR("Failed to allocate a GPtrArray."); - goto error; - } - muxer_comp->self_comp = self_comp; bt_self_component_set_data( bt_self_component_filter_as_self_component(self_comp), muxer_comp); - status = ensure_available_input_port(self_comp); + status = add_available_input_port(self_comp); if (status != BT_SELF_COMPONENT_STATUS_OK) { BT_LOGE("Cannot ensure that at least one muxer component's input port is available: " "muxer-comp-addr=%p, status=%s", @@ -415,8 +376,7 @@ void muxer_finalize(bt_self_component_filter *self_comp) static bt_self_component_port_input_message_iterator * -create_msg_iter_on_input_port( - bt_self_component_port_input *self_port, int *ret) +create_msg_iter_on_input_port(bt_self_component_port_input *self_port) { const bt_port *port = bt_self_component_port_as_port( bt_self_component_port_input_as_self_component_port( @@ -424,8 +384,6 @@ create_msg_iter_on_input_port( bt_self_component_port_input_message_iterator *msg_iter = NULL; - BT_ASSERT(ret); - *ret = 0; BT_ASSERT(port); BT_ASSERT(bt_port_is_connected(port)); @@ -438,7 +396,6 @@ create_msg_iter_on_input_port( BT_LOGE("Cannot create upstream message iterator on input port: " "port-addr=%p, port-name=\"%s\"", port, bt_port_get_name(port)); - *ret = -1; goto end; } @@ -518,90 +475,6 @@ bt_self_message_iterator_status muxer_upstream_msg_iter_next( return status; } -static -int muxer_msg_iter_handle_newly_connected_ports( - struct muxer_msg_iter *muxer_msg_iter) -{ - int ret = 0; - - BT_LOGV("Handling newly connected ports: " - "muxer-msg-iter-addr=%p", muxer_msg_iter); - - /* - * Here we create one upstream message iterator for each - * newly connected port. We do NOT perform an initial "next" on - * those new upstream message iterators: they are - * invalidated, to be validated later. The list of newly - * connected ports to handle here is updated by - * muxer_port_connected(). - */ - while (true) { - GList *node = muxer_msg_iter->newly_connected_self_ports; - bt_self_component_port_input *self_port; - const bt_port *port; - bt_self_component_port_input_message_iterator * - upstream_msg_iter = NULL; - struct muxer_upstream_msg_iter *muxer_upstream_msg_iter; - - if (!node) { - break; - } - - self_port = node->data; - port = bt_self_component_port_as_port( - bt_self_component_port_input_as_self_component_port( - (self_port))); - BT_ASSERT(port); - - if (!bt_port_is_connected(port)) { - /* - * Looks like this port is not connected - * anymore: we can't create an upstream - * message iterator on its (non-existing) - * connection in this case. - */ - goto remove_node; - } - - upstream_msg_iter = create_msg_iter_on_input_port( - self_port, &ret); - if (ret) { - /* create_msg_iter_on_input_port() logs errors */ - BT_ASSERT(!upstream_msg_iter); - goto error; - } - - muxer_upstream_msg_iter = - muxer_msg_iter_add_upstream_msg_iter( - muxer_msg_iter, upstream_msg_iter); - BT_SELF_COMPONENT_PORT_INPUT_MESSAGE_ITERATOR_PUT_REF_AND_RESET(upstream_msg_iter); - if (!muxer_upstream_msg_iter) { - /* - * muxer_msg_iter_add_upstream_msg_iter() - * logs errors. - */ - goto error; - } - -remove_node: - bt_self_component_port_input_message_iterator_put_ref(upstream_msg_iter); - muxer_msg_iter->newly_connected_self_ports = - g_list_delete_link( - muxer_msg_iter->newly_connected_self_ports, - node); - } - - goto end; - -error: - if (ret >= 0) { - ret = -1; - } - -end: - return ret; -} - static int get_msg_ts_ns(struct muxer_comp *muxer_comp, struct muxer_msg_iter *muxer_msg_iter, @@ -915,7 +788,6 @@ end: * This function does NOT: * * * Update any upstream message iterator. - * * Check for newly connected ports. * * Check the upstream message iterators to retry. * * On sucess, this function sets *muxer_upstream_msg_iter to the @@ -1078,47 +950,16 @@ bt_self_message_iterator_status muxer_msg_iter_do_next_one( struct muxer_msg_iter *muxer_msg_iter, const bt_message **msg) { - bt_self_message_iterator_status status = - BT_SELF_MESSAGE_ITERATOR_STATUS_OK; + bt_self_message_iterator_status status; struct muxer_upstream_msg_iter *muxer_upstream_msg_iter = NULL; int64_t next_return_ts; - while (true) { - int ret = muxer_msg_iter_handle_newly_connected_ports( - muxer_msg_iter); - - if (ret) { - BT_LOGE("Cannot handle newly connected input ports for muxer's message iterator: " - "muxer-comp-addr=%p, muxer-msg-iter-addr=%p, " - "ret=%d", - muxer_comp, muxer_msg_iter, ret); - status = BT_SELF_MESSAGE_ITERATOR_STATUS_ERROR; - goto end; - } - - status = validate_muxer_upstream_msg_iters(muxer_msg_iter); - if (status != BT_SELF_MESSAGE_ITERATOR_STATUS_OK) { - /* validate_muxer_upstream_msg_iters() logs details */ - goto end; - } - - /* - * At this point, we know that all the existing upstream - * message iterators are valid. However the - * operations to validate them (during - * validate_muxer_upstream_msg_iters()) may have - * connected new ports. If no ports were connected - * during this operation, exit the loop. - */ - if (!muxer_msg_iter->newly_connected_self_ports) { - BT_LOGV("Not breaking this loop: muxer's message iterator still has newly connected input ports to handle: " - "muxer-comp-addr=%p", muxer_comp); - break; - } + status = validate_muxer_upstream_msg_iters(muxer_msg_iter); + if (status != BT_SELF_MESSAGE_ITERATOR_STATUS_OK) { + /* validate_muxer_upstream_msg_iters() logs details */ + goto end; } - BT_ASSERT(!muxer_msg_iter->newly_connected_self_ports); - /* * At this point we know that all the existing upstream * message iterators are valid. We can find the one, @@ -1227,23 +1068,17 @@ void destroy_muxer_msg_iter(struct muxer_msg_iter *muxer_msg_iter) muxer_msg_iter->muxer_upstream_msg_iters, TRUE); } - g_list_free(muxer_msg_iter->newly_connected_self_ports); g_free(muxer_msg_iter); } static -int muxer_msg_iter_init_newly_connected_ports(struct muxer_comp *muxer_comp, +int muxer_msg_iter_init_upstream_iterators(struct muxer_comp *muxer_comp, struct muxer_msg_iter *muxer_msg_iter) { int64_t count; int64_t i; int ret = 0; - /* - * Add the connected input ports to this muxer message - * iterator's list of newly connected ports. They will be - * handled by muxer_msg_iter_handle_newly_connected_ports(). - */ count = bt_component_filter_get_input_port_count( bt_self_component_filter_as_component_filter( muxer_comp->self_comp)); @@ -1255,6 +1090,8 @@ int muxer_msg_iter_init_newly_connected_ports(struct muxer_comp *muxer_comp, } for (i = 0; i < count; i++) { + bt_self_component_port_input_message_iterator *upstream_msg_iter; + struct muxer_upstream_msg_iter *muxer_upstream_msg_iter; bt_self_component_port_input *self_port = bt_self_component_filter_borrow_input_port_by_index( muxer_comp->self_comp, i); @@ -1267,29 +1104,28 @@ int muxer_msg_iter_init_newly_connected_ports(struct muxer_comp *muxer_comp, BT_ASSERT(port); if (!bt_port_is_connected(port)) { - BT_LOGD("Skipping input port: not connected: " - "muxer-comp-addr=%p, port-addr=%p, port-name\"%s\"", - muxer_comp, port, bt_port_get_name(port)); + /* Skip non-connected port */ continue; } - muxer_msg_iter->newly_connected_self_ports = - g_list_append( - muxer_msg_iter->newly_connected_self_ports, - self_port); - if (!muxer_msg_iter->newly_connected_self_ports) { - BT_LOGE("Cannot append port to muxer's message iterator list of newly connected input ports: " - "port-addr=%p, port-name=\"%s\", " - "muxer-msg-iter-addr=%p", port, - bt_port_get_name(port), muxer_msg_iter); + upstream_msg_iter = create_msg_iter_on_input_port(self_port); + if (!upstream_msg_iter) { + /* create_msg_iter_on_input_port() logs errors */ + BT_ASSERT(!upstream_msg_iter); ret = -1; goto end; } - BT_LOGD("Appended port to muxer's message iterator list of newly connected input ports: " - "port-addr=%p, port-name=\"%s\", " - "muxer-msg-iter-addr=%p", port, - bt_port_get_name(port), muxer_msg_iter); + muxer_upstream_msg_iter = + muxer_msg_iter_add_upstream_msg_iter( + muxer_msg_iter, upstream_msg_iter); + bt_self_component_port_input_message_iterator_put_ref( + upstream_msg_iter); + if (!muxer_upstream_msg_iter) { + /* muxer_msg_iter_add_upstream_msg_iter() logs errors */ + ret = -1; + goto end; + } } end: @@ -1343,19 +1179,10 @@ bt_self_message_iterator_status muxer_msg_iter_init( goto error; } - /* - * Add the muxer message iterator to the component's array - * of muxer message iterators here because - * muxer_msg_iter_init_newly_connected_ports() can cause - * muxer_port_connected() to be called, which adds the newly - * connected port to each muxer message iterator's list of - * newly connected ports. - */ - g_ptr_array_add(muxer_comp->muxer_msg_iters, muxer_msg_iter); - ret = muxer_msg_iter_init_newly_connected_ports(muxer_comp, + ret = muxer_msg_iter_init_upstream_iterators(muxer_comp, muxer_msg_iter); if (ret) { - BT_LOGE("Cannot initialize newly connected input ports for muxer component's message iterator: " + BT_LOGE("Cannot initialize connected input ports for muxer component's message iterator: " "comp-addr=%p, muxer-comp-addr=%p, " "muxer-msg-iter-addr=%p, msg-iter-addr=%p, ret=%d", self_comp, muxer_comp, muxer_msg_iter, @@ -1363,8 +1190,7 @@ bt_self_message_iterator_status muxer_msg_iter_init( goto error; } - bt_self_message_iterator_set_data(self_msg_iter, - muxer_msg_iter); + bt_self_message_iterator_set_data(self_msg_iter, muxer_msg_iter); BT_LOGD("Initialized muxer component's message iterator: " "comp-addr=%p, muxer-comp-addr=%p, muxer-msg-iter-addr=%p, " "msg-iter-addr=%p", @@ -1372,15 +1198,8 @@ bt_self_message_iterator_status muxer_msg_iter_init( goto end; error: - if (g_ptr_array_index(muxer_comp->muxer_msg_iters, - muxer_comp->muxer_msg_iters->len - 1) == muxer_msg_iter) { - g_ptr_array_remove_index(muxer_comp->muxer_msg_iters, - muxer_comp->muxer_msg_iters->len - 1); - } - destroy_muxer_msg_iter(muxer_msg_iter); - bt_self_message_iterator_set_data(self_msg_iter, - NULL); + bt_self_message_iterator_set_data(self_msg_iter, NULL); status = BT_SELF_MESSAGE_ITERATOR_STATUS_ERROR; end: @@ -1406,9 +1225,7 @@ void muxer_msg_iter_finalize( "msg-iter-addr=%p", self_comp, muxer_comp, muxer_msg_iter, self_msg_iter); - if (muxer_comp) { - (void) g_ptr_array_remove_fast(muxer_comp->muxer_msg_iters, - muxer_msg_iter); + if (muxer_msg_iter) { destroy_muxer_msg_iter(muxer_msg_iter); } } @@ -1459,69 +1276,17 @@ bt_self_component_status muxer_input_port_connected( bt_self_component_port_input *self_port, const bt_port_output *other_port) { - bt_self_component_status status = BT_SELF_COMPONENT_STATUS_OK; - const bt_port *port = bt_self_component_port_as_port( - bt_self_component_port_input_as_self_component_port( - self_port)); - struct muxer_comp *muxer_comp = - bt_self_component_get_data( - bt_self_component_filter_as_self_component( - self_comp)); - size_t i; - int ret; - - BT_ASSERT(port); - BT_ASSERT(muxer_comp); - BT_LOGD("Port connected: " - "comp-addr=%p, muxer-comp-addr=%p, " - "port-addr=%p, port-name=\"%s\", " - "other-port-addr=%p, other-port-name=\"%s\"", - self_comp, muxer_comp, self_port, bt_port_get_name(port), - other_port, - bt_port_get_name(bt_port_output_as_port_const(other_port))); - - for (i = 0; i < muxer_comp->muxer_msg_iters->len; i++) { - struct muxer_msg_iter *muxer_msg_iter = - g_ptr_array_index(muxer_comp->muxer_msg_iters, i); - - /* - * Add this port to the list of newly connected ports - * for this muxer message iterator. We append at - * the end of this list while - * muxer_msg_iter_handle_newly_connected_ports() - * removes the nodes from the beginning. - */ - muxer_msg_iter->newly_connected_self_ports = - g_list_append( - muxer_msg_iter->newly_connected_self_ports, - self_port); - if (!muxer_msg_iter->newly_connected_self_ports) { - BT_LOGE("Cannot append port to muxer's message iterator list of newly connected input ports: " - "port-addr=%p, port-name=\"%s\", " - "muxer-msg-iter-addr=%p", self_port, - bt_port_get_name(port), muxer_msg_iter); - status = BT_SELF_COMPONENT_STATUS_ERROR; - goto end; - } - - BT_LOGD("Appended port to muxer's message iterator list of newly connected input ports: " - "port-addr=%p, port-name=\"%s\", " - "muxer-msg-iter-addr=%p", self_port, - bt_port_get_name(port), muxer_msg_iter); - } + bt_self_component_status status; - /* One less available input port */ - muxer_comp->available_input_ports--; - ret = ensure_available_input_port(self_comp); - if (ret) { + status = add_available_input_port(self_comp); + if (status) { /* * Only way to report an error later since this * method does not return anything. */ - BT_LOGE("Cannot ensure that at least one muxer component's input port is available: " - "muxer-comp-addr=%p, status=%s", - muxer_comp, bt_self_component_status_string(ret)); - status = BT_SELF_COMPONENT_STATUS_ERROR; + BT_LOGE("Cannot add one muxer component's input port: " + "status=%s", + bt_self_component_status_string(status)); goto end; } diff --git a/plugins/utils/plugin.c b/plugins/utils/plugin.c index d8fc45d3..a02ebaaa 100644 --- a/plugins/utils/plugin.c +++ b/plugins/utils/plugin.c @@ -38,8 +38,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_INPUT_PORT_CONNECTED_METHOD(dummy, - dummy_port_connected); +BT_PLUGIN_SINK_COMPONENT_CLASS_GRAPH_IS_CONFIGURED_METHOD(dummy, + dummy_graph_is_configured); BT_PLUGIN_SINK_COMPONENT_CLASS_DESCRIPTION(dummy, "Consume messages and discard them."); @@ -47,8 +47,8 @@ BT_PLUGIN_SINK_COMPONENT_CLASS_DESCRIPTION(dummy, BT_PLUGIN_SINK_COMPONENT_CLASS(counter, counter_consume); BT_PLUGIN_SINK_COMPONENT_CLASS_INIT_METHOD(counter, counter_init); BT_PLUGIN_SINK_COMPONENT_CLASS_FINALIZE_METHOD(counter, counter_finalize); -BT_PLUGIN_SINK_COMPONENT_CLASS_INPUT_PORT_CONNECTED_METHOD(counter, - counter_port_connected); +BT_PLUGIN_SINK_COMPONENT_CLASS_GRAPH_IS_CONFIGURED_METHOD(counter, + counter_graph_is_configured); BT_PLUGIN_SINK_COMPONENT_CLASS_DESCRIPTION(counter, "Count messages and print the results."); -- 2.34.1