lib: add sink component class's "graph is configured" method
authorPhilippe Proulx <eeppeliteloop@gmail.com>
Thu, 21 Feb 2019 22:12:11 +0000 (17:12 -0500)
committerFrancis Deslauriers <francis.deslauriers@efficios.com>
Thu, 2 May 2019 20:50:15 +0000 (20:50 +0000)
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 <eeppeliteloop@gmail.com>
20 files changed:
include/babeltrace/graph/component-class-internal.h
include/babeltrace/graph/component-class-sink.h
include/babeltrace/graph/component-sink-internal.h
include/babeltrace/graph/graph-internal.h
include/babeltrace/plugin/plugin-dev.h
lib/graph/component-class.c
lib/graph/component.c
lib/graph/graph.c
lib/graph/iterator.c
lib/lib-logging.c
lib/plugin/plugin-so.c
plugins/text/plugin.c
plugins/text/pretty/pretty.c
plugins/text/pretty/pretty.h
plugins/utils/counter/counter.c
plugins/utils/counter/counter.h
plugins/utils/dummy/dummy.c
plugins/utils/dummy/dummy.h
plugins/utils/muxer/muxer.c
plugins/utils/plugin.c

index 953fa91a4eefdf3a0b82807618bb6e43f32933c4..b6e71881e106fc5d352c016a8d167ec8d563e16a 100644 (file)
@@ -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;
 };
index 003f549f24ee0508e5e35cfdc67d8db6e91666cb..601974b9774751edc06f3fe0f33e490a2de2937f 100644 (file)
@@ -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);
index 74e5af927e39967d94254048c66335b47a3b8258..164b96356b3c9cf071f089fbdcb947734fcdda8b 100644 (file)
@@ -32,6 +32,7 @@
 
 struct bt_component_sink {
        struct bt_component parent;
+       bool graph_is_configured_method_called;
 };
 
 BT_HIDDEN
index dc1399a8e93fde94fde2f7ae75d6d6684e430eac..97289cf0f168e4b36d349845a5b0de199e46e34f 100644 (file)
@@ -27,6 +27,8 @@
 #include <babeltrace/graph/graph.h>
 #include <babeltrace/graph/connection-internal.h>
 #include <babeltrace/graph/message-const.h>
+#include <babeltrace/graph/component-internal.h>
+#include <babeltrace/graph/component-sink-internal.h>
 #include <babeltrace/babeltrace-internal.h>
 #include <babeltrace/object-internal.h>
 #include <babeltrace/object-pool-internal.h>
 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 */
index 1be7aa9388c4284ae676598b454f489e546bebf3..66b79ded4d5055edcefd559eccdd36705f0ba2b5 100644 (file)
@@ -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
index 7f90720e91059151b57cd735b58b44b2d4dd229a..314cc04ec09ed4626f6b4bc0e3f38be08af2fa82 100644 (file)
@@ -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)
index 48454d649ca56ed4369664a74c075cccba135db2..53c9cd6defa4a12d9cac248e78ac4073e49b200e 100644 (file)
@@ -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);
 
index d5fc0b6b54c36eec69ad9a2f89204469da46f6fa..49933d54931588dbd88ad7f6eddbc8f35bd6c38f 100644 (file)
@@ -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);
index ddfe417cf607841490d41b5f1d3cb04046a5d04d..c97ec94d94953ce2247fe3900da9864070b19c13 100644 (file)
@@ -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(
index a1b9a7eab4b2e26119786079598677562cfb0dfc..3fd96dd1ac401ecc2e55931d67b6bb1d340ef88f 100644 (file)
@@ -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;
index ed8d5e297712395174cec3075bfe82c254188c50..ac0ec75b206c777f37d744bb8d1c395be1712a5d 100644 (file)
@@ -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();
index 55507de5e11b7f191f5dadf158bbb623c3d2d36e..bdd2789cccf837f1520e8e9f1d63fa751d05cf9e 100644 (file)
@@ -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).");
 
index d83b30c160123b85b3693a4bfab665e90118eaff..1b5729ab30c71081654ea90f7ce225e7fd44717c 100644 (file)
@@ -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;
        }
index d9e03c90ce7e0343566bfa1e06d08dd3314aab09..e1027277a4269a814bb2ce27b3fef0b0b9a9ca4c 100644 (file)
@@ -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);
index fa75b6aeb5e3b7d4784dc292a8d3343339c841b5..ec0a8dba8633a83641254f9b555ae6a2930fba65 100644 (file)
@@ -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;
index b3a93b6ff92a9286ac34506925c4755712e34f62..e4cbdde7885864d891215c4f433bed9f5c5c8666 100644 (file)
@@ -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);
index e0c44c5bffcfd7537c74b39d09ba6f7166b25d9a..61cdfe0205324687e1695677841a7471203a1517 100644 (file)
@@ -26,6 +26,9 @@
 #include <babeltrace/assert-internal.h>
 #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;
index ed2ddfdbeae48eff8fccc336d9d2043c3c822837..5df1a2dec468f61432f81ee8caf989dc73a237bc 100644 (file)
@@ -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(
index a6a71b7a8ce3283faf27a21ca8e34ef90199a969..aa5cbb23645c1bef5522e5c2cfc0da25b478962d 100644 (file)
 #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;
        }
 
index d8fc45d39ba5b4ef8cbdf2f7986c549c5066874e..a02ebaaa92a5ef5a2d9bc869dd2a4214a66b25ce 100644 (file)
@@ -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.");
 
This page took 0.047284 seconds and 4 git commands to generate.