lib: Make graph listeners return an error status
authorSimon Marchi <simon.marchi@efficios.com>
Thu, 16 May 2019 16:10:18 +0000 (12:10 -0400)
committerPhilippe Proulx <eeppeliteloop@gmail.com>
Wed, 5 Jun 2019 17:47:34 +0000 (13:47 -0400)
Currently, if a graph listener fails for some reason (for example, an
uncaught exception in Python), no error is reported to the initial
caller, so it has no way to handle the failure properly.  If a listener
fails, we can't really trust that the execution will proceed as
intended, so it is likely that the caller wants to exit with an error
too.

All the listener typedefs are updated to return a new type,
bt_graph_listener_status.  If any listener fails, the graph is put in
"faulty" state and we return an error up the stack.

If a listener fails, the action is not rolled back.  This means that if
a port added listener fails, the port that was added is not removed.  If
a ports connected listener fails, the connection is not undone.

A few call sites needed to be updated.  An interesting one is in
cli/babeltrace.c.  Where we previously aborted, we can now return an
error and exit cleanly.

The Python bindings is another user of the listener API.  I have
modified the functions in native_bt_graph.i to keep the code building,
but the errors are currently not propagated from the Python callback.
This will be done in a subsequent patch.

Change-Id: I115773c405162f7b1c617cf4a8302b980315e14d
Signed-off-by: Simon Marchi <simon.marchi@efficios.com>
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1316
Reviewed-by: Philippe Proulx <eeppeliteloop@gmail.com>
Tested-by: jenkins
bindings/python/bt2/bt2/native_bt_graph.i
cli/babeltrace.c
include/babeltrace/graph/component-internal.h
include/babeltrace/graph/graph-internal.h
include/babeltrace/graph/graph.h
lib/graph/component-filter.c
lib/graph/component-sink.c
lib/graph/component-source.c
lib/graph/component.c
lib/graph/graph.c
tests/lib/test_graph_topo.c

index c898c78ed653eb3aaa1eb4f1ef04ebe214ed4508..bf6b5cdd02ae6327e2fb305688feae23159bb14f 100644 (file)
@@ -121,42 +121,57 @@ extern void bt_graph_put_ref(const bt_graph *graph);
 
 /* From graph.h */
 
-typedef void (*bt_graph_filter_component_input_port_added_listener_func)(
+typedef enum bt_graph_listener_status {
+       BT_GRAPH_LISTENER_STATUS_OK = 0,
+       BT_GRAPH_LISTENER_STATUS_ERROR = -1,
+       BT_GRAPH_LISTENER_STATUS_NOMEM = -12,
+} bt_graph_listener_status;
+
+
+typedef bt_graph_listener_status
+(*bt_graph_filter_component_input_port_added_listener_func)(
                const bt_component_filter *component,
                const bt_port_input *port, void *data);
 
-typedef void (*bt_graph_sink_component_input_port_added_listener_func)(
+typedef bt_graph_listener_status
+(*bt_graph_sink_component_input_port_added_listener_func)(
                const bt_component_sink *component,
                const bt_port_input *port, void *data);
 
-typedef void (*bt_graph_source_component_output_port_added_listener_func)(
+typedef bt_graph_listener_status
+(*bt_graph_source_component_output_port_added_listener_func)(
                const bt_component_source *component,
                const bt_port_output *port, void *data);
 
-typedef void (*bt_graph_filter_component_output_port_added_listener_func)(
+typedef bt_graph_listener_status
+(*bt_graph_filter_component_output_port_added_listener_func)(
                const bt_component_filter *component,
                const bt_port_output *port, void *data);
 
-typedef void (*bt_graph_source_filter_component_ports_connected_listener_func)(
+typedef bt_graph_listener_status
+(*bt_graph_source_filter_component_ports_connected_listener_func)(
                const bt_component_source *source_component,
                const bt_component_filter *filter_component,
                const bt_port_output *upstream_port,
                const bt_port_input *downstream_port, void *data);
 
-typedef void (*bt_graph_source_sink_component_ports_connected_listener_func)(
+typedef bt_graph_listener_status
+(*bt_graph_source_sink_component_ports_connected_listener_func)(
                const bt_component_source *source_component,
                const bt_component_sink *sink_component,
                const bt_port_output *upstream_port,
                const bt_port_input *downstream_port, void *data);
 
-typedef void (*bt_graph_filter_filter_component_ports_connected_listener_func)(
+typedef bt_graph_listener_status
+(*bt_graph_filter_filter_component_ports_connected_listener_func)(
                const bt_component_filter *filter_component_upstream,
                const bt_component_filter *filter_component_downstream,
                const bt_port_output *upstream_port,
                const bt_port_input *downstream_port,
                void *data);
 
-typedef void (*bt_graph_filter_sink_component_ports_connected_listener_func)(
+typedef bt_graph_listener_status
+(*bt_graph_filter_sink_component_ports_connected_listener_func)(
                const bt_component_filter *filter_component,
                const bt_component_sink *sink_component,
                const bt_port_output *upstream_port,
@@ -274,11 +289,11 @@ static void graph_listener_removed(void *py_callable)
        Py_DECREF(py_callable);
 }
 
-static void
+static bt_graph_listener_status
 port_added_listener(
        const void *component,
        swig_type_info *component_swig_type,
-       bt_component_class_type component_class_type,   
+       bt_component_class_type component_class_type,
        const void *port,
        swig_type_info *port_swig_type,
        bt_port_type port_type,
@@ -287,6 +302,7 @@ port_added_listener(
        PyObject *py_component_ptr = NULL;
        PyObject *py_port_ptr = NULL;
        PyObject *py_res = NULL;
+       bt_graph_listener_status status = BT_GRAPH_LISTENER_STATUS_OK;
 
        py_component_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(component), component_swig_type, 0);
        if (!py_component_ptr) {
@@ -313,40 +329,42 @@ end:
        Py_XDECREF(py_res);
        Py_XDECREF(py_port_ptr);
        Py_XDECREF(py_component_ptr);
+
+       return status;
 }
 
-static void
+static bt_graph_listener_status
 source_component_output_port_added_listener(const bt_component_source *component_source,
                                            const bt_port_output *port_output, void *py_callable)
 {
-       port_added_listener(
+       return port_added_listener(
                component_source, SWIGTYPE_p_bt_component_source, BT_COMPONENT_CLASS_TYPE_SOURCE,
                port_output, SWIGTYPE_p_bt_port_output, BT_PORT_TYPE_OUTPUT, py_callable);
 }
 
-static void
+static bt_graph_listener_status
 filter_component_input_port_added_listener(const bt_component_filter *component_filter,
                                           const bt_port_input *port_input, void *py_callable)
 {
-       port_added_listener(
+       return port_added_listener(
                component_filter, SWIGTYPE_p_bt_component_filter, BT_COMPONENT_CLASS_TYPE_FILTER,
                port_input, SWIGTYPE_p_bt_port_input, BT_PORT_TYPE_INPUT, py_callable);
 }
 
-static void
+static bt_graph_listener_status
 filter_component_output_port_added_listener(const bt_component_filter *component_filter,
                                            const bt_port_output *port_output, void *py_callable)
 {
-       port_added_listener(
+       return port_added_listener(
                component_filter, SWIGTYPE_p_bt_component_filter, BT_COMPONENT_CLASS_TYPE_FILTER,
                port_output, SWIGTYPE_p_bt_port_output, BT_PORT_TYPE_OUTPUT, py_callable);
 }
 
-static void
+static bt_graph_listener_status
 sink_component_input_port_added_listener(const bt_component_sink *component_sink,
                                         const bt_port_input *port_input, void *py_callable)
 {
-       port_added_listener(
+       return port_added_listener(
                component_sink, SWIGTYPE_p_bt_component_sink, BT_COMPONENT_CLASS_TYPE_SINK,
                port_input, SWIGTYPE_p_bt_port_input, BT_PORT_TYPE_INPUT, py_callable);
 }
@@ -455,7 +473,7 @@ end:
        return py_listener_ids;
 }
 
-static void
+static bt_graph_listener_status
 ports_connected_listener(const bt_port_output *upstream_port,
                         const bt_port_input *downstream_port,
                         void *py_callable)
@@ -463,6 +481,7 @@ ports_connected_listener(const bt_port_output *upstream_port,
        PyObject *py_upstream_port_ptr = NULL;
        PyObject *py_downstream_port_ptr = NULL;
        PyObject *py_res = NULL;
+       bt_graph_listener_status status = BT_GRAPH_LISTENER_STATUS_OK;
 
        py_upstream_port_ptr = SWIG_NewPointerObj(
                SWIG_as_voidptr(upstream_port), SWIGTYPE_p_bt_port_output, 0);
@@ -490,46 +509,52 @@ ports_connected_listener(const bt_port_output *upstream_port,
        Py_DECREF(py_upstream_port_ptr);
        Py_DECREF(py_downstream_port_ptr);
        Py_XDECREF(py_res);
+
+       return status;
 }
 
-static void
+static bt_graph_listener_status
 source_filter_component_ports_connected_listener(
        const bt_component_source *source_component,
        const bt_component_filter *filter_component,
        const bt_port_output *upstream_port,
        const bt_port_input *downstream_port, void *py_callable)
 {
-       ports_connected_listener(upstream_port, downstream_port, py_callable);
+       return ports_connected_listener(upstream_port, downstream_port,
+                       py_callable);
 }
 
-static void
+static bt_graph_listener_status
 source_sink_component_ports_connected_listener(
        const bt_component_source *source_component,
        const bt_component_sink *sink_component,
        const bt_port_output *upstream_port,
        const bt_port_input *downstream_port, void *py_callable)
 {
-       ports_connected_listener(upstream_port, downstream_port, py_callable);
+       return ports_connected_listener(upstream_port, downstream_port,
+                       py_callable);
 }
 
-static void
+static bt_graph_listener_status
 filter_filter_component_ports_connected_listener(
        const bt_component_filter *filter_component_left,
        const bt_component_filter *filter_component_right,
        const bt_port_output *upstream_port,
        const bt_port_input *downstream_port, void *py_callable)
 {
-       ports_connected_listener(upstream_port, downstream_port, py_callable);
+       return ports_connected_listener(upstream_port, downstream_port,
+                       py_callable);
 }
 
-static void
+static bt_graph_listener_status
 filter_sink_component_ports_connected_listener(
        const bt_component_filter *filter_component,
        const bt_component_sink *sink_component,
        const bt_port_output *upstream_port,
        const bt_port_input *downstream_port, void *py_callable)
 {
-       ports_connected_listener(upstream_port, downstream_port, py_callable);
+       return ports_connected_listener(upstream_port, downstream_port,
+                       py_callable);
 }
 
 
index 791c6c8eba18190c6a670e634e2c735866fa25f9..ad5f22f716208a619977552e7d4202508a3f51d7 100644 (file)
@@ -1998,11 +1998,13 @@ end:
 }
 
 static
-void graph_output_port_added_listener(struct cmd_run_ctx *ctx,
+bt_graph_listener_status
+graph_output_port_added_listener(struct cmd_run_ctx *ctx,
                const bt_port_output *out_port)
 {
        const bt_component *comp;
        const bt_port *port = bt_port_output_as_port_const(out_port);
+       bt_graph_listener_status ret = BT_GRAPH_LISTENER_STATUS_OK;
 
        comp = bt_port_borrow_component_const(port);
        BT_LOGI("Port added to a graph's component: comp-addr=%p, "
@@ -2027,27 +2029,28 @@ void graph_output_port_added_listener(struct cmd_run_ctx *ctx,
        if (cmd_run_ctx_connect_upstream_port(ctx, out_port)) {
                BT_LOGF_STR("Cannot connect upstream port.");
                fprintf(stderr, "Added port could not be connected: aborting\n");
-               abort();
+               ret = BT_GRAPH_LISTENER_STATUS_ERROR;
+               goto end;
        }
 
 end:
-       return;
+       return ret;
 }
 
 static
-void graph_source_output_port_added_listener(
+bt_graph_listener_status graph_source_output_port_added_listener(
                const bt_component_source *component,
                const bt_port_output *port, void *data)
 {
-       graph_output_port_added_listener(data, port);
+       return graph_output_port_added_listener(data, port);
 }
 
 static
-void graph_filter_output_port_added_listener(
+bt_graph_listener_status graph_filter_output_port_added_listener(
                const bt_component_filter *component,
                const bt_port_output *port, void *data)
 {
-       graph_output_port_added_listener(data, port);
+       return graph_output_port_added_listener(data, port);
 }
 
 static
index d5555f1a8fe1c80cfb6ecf9c92e637bd2be70f15..452e6c5aa5c9bbb735ed22a86b44d8cf65dfa530 100644 (file)
@@ -116,14 +116,14 @@ struct bt_port_output *bt_component_borrow_output_port_by_name(
                struct bt_component *comp, const char *name);
 
 BT_HIDDEN
-struct bt_port_input *bt_component_add_input_port(
+enum bt_self_component_status bt_component_add_input_port(
                struct bt_component *component, const char *name,
-               void *user_data);
+               void *user_data, struct bt_port **port);
 
 BT_HIDDEN
-struct bt_port_output *bt_component_add_output_port(
+enum bt_self_component_status bt_component_add_output_port(
                struct bt_component *component, const char *name,
-               void *user_data);
+               void *user_data, struct bt_port **port);
 
 BT_HIDDEN
 void bt_component_remove_port(struct bt_component *component,
index d9ae46f6b0573785e462e8c6f8f8f52a3145a43f..fce624fb466fe96a0a6fbe852f8ebee57cd740aa 100644 (file)
@@ -139,11 +139,13 @@ enum bt_graph_status bt_graph_consume_sink_no_check(struct bt_graph *graph,
                struct bt_component_sink *sink);
 
 BT_HIDDEN
-void bt_graph_notify_port_added(struct bt_graph *graph, struct bt_port *port);
+enum bt_graph_listener_status bt_graph_notify_port_added(struct bt_graph *graph,
+               struct bt_port *port);
 
 BT_HIDDEN
-void bt_graph_notify_ports_connected(struct bt_graph *graph,
-               struct bt_port *upstream_port, struct bt_port *downstream_port);
+enum bt_graph_listener_status bt_graph_notify_ports_connected(
+               struct bt_graph *graph, struct bt_port *upstream_port,
+               struct bt_port *downstream_port);
 
 BT_HIDDEN
 void bt_graph_remove_connection(struct bt_graph *graph,
@@ -285,4 +287,13 @@ end:
        return status;
 }
 
+static inline
+void bt_graph_make_faulty(struct bt_graph *graph)
+{
+       graph->config_state = BT_GRAPH_CONFIGURATION_STATE_FAULTY;
+#ifdef BT_LIB_LOGD
+       BT_LIB_LOGD("Set graph's state to faulty: %![graph-]+g", graph);
+#endif
+}
+
 #endif /* BABELTRACE_GRAPH_GRAPH_INTERNAL_H */
index 967bc91dc6e99519d191d5435b83a88eae6350ea..18069603bfb5a3cf4cac23c49864dd1595c80f6d 100644 (file)
 extern "C" {
 #endif
 
-typedef void (*bt_graph_filter_component_input_port_added_listener_func)(
+typedef enum bt_graph_listener_status {
+       BT_GRAPH_LISTENER_STATUS_OK = 0,
+       BT_GRAPH_LISTENER_STATUS_ERROR = -1,
+       BT_GRAPH_LISTENER_STATUS_NOMEM = -12,
+} bt_graph_listener_status;
+
+typedef bt_graph_listener_status
+(*bt_graph_filter_component_input_port_added_listener_func)(
                const bt_component_filter *component,
                const bt_port_input *port, void *data);
 
-typedef void (*bt_graph_sink_component_input_port_added_listener_func)(
+typedef bt_graph_listener_status
+(*bt_graph_sink_component_input_port_added_listener_func)(
                const bt_component_sink *component,
                const bt_port_input *port, void *data);
 
-typedef void (*bt_graph_source_component_output_port_added_listener_func)(
+typedef bt_graph_listener_status
+(*bt_graph_source_component_output_port_added_listener_func)(
                const bt_component_source *component,
                const bt_port_output *port, void *data);
 
-typedef void (*bt_graph_filter_component_output_port_added_listener_func)(
+typedef bt_graph_listener_status
+(*bt_graph_filter_component_output_port_added_listener_func)(
                const bt_component_filter *component,
                const bt_port_output *port, void *data);
 
-typedef void (*bt_graph_source_filter_component_ports_connected_listener_func)(
+typedef bt_graph_listener_status
+(*bt_graph_source_filter_component_ports_connected_listener_func)(
                const bt_component_source *source_component,
                const bt_component_filter *filter_component,
                const bt_port_output *upstream_port,
                const bt_port_input *downstream_port, void *data);
 
-typedef void (*bt_graph_source_sink_component_ports_connected_listener_func)(
+typedef bt_graph_listener_status
+(*bt_graph_source_sink_component_ports_connected_listener_func)(
                const bt_component_source *source_component,
                const bt_component_sink *sink_component,
                const bt_port_output *upstream_port,
                const bt_port_input *downstream_port, void *data);
 
-typedef void (*bt_graph_filter_filter_component_ports_connected_listener_func)(
+typedef bt_graph_listener_status
+(*bt_graph_filter_filter_component_ports_connected_listener_func)(
                const bt_component_filter *filter_component_upstream,
                const bt_component_filter *filter_component_downstream,
                const bt_port_output *upstream_port,
                const bt_port_input *downstream_port,
                void *data);
 
-typedef void (*bt_graph_filter_sink_component_ports_connected_listener_func)(
+typedef bt_graph_listener_status
+(*bt_graph_filter_sink_component_ports_connected_listener_func)(
                const bt_component_filter *filter_component,
                const bt_component_sink *sink_component,
                const bt_port_output *upstream_port,
index c1c730ca3bbb15f0a4335588fdc77348cb2d1e58..b59543b8d95348cb4682a7109212be3db380d990 100644 (file)
@@ -116,13 +116,12 @@ enum bt_self_component_status bt_self_component_filter_add_output_port(
                struct bt_self_component_port_output **self_port)
 {
        struct bt_component *comp = (void *) self_comp;
-       int status = BT_SELF_COMPONENT_STATUS_OK;
+       enum bt_self_component_status status;
        struct bt_port *port = NULL;
 
        /* bt_component_add_output_port() logs details and errors */
-       port = (void *) bt_component_add_output_port(comp, name, user_data);
-       if (!port) {
-               status = BT_SELF_COMPONENT_STATUS_NOMEM;
+       status = bt_component_add_output_port(comp, name, user_data, &port);
+       if (status != BT_SELF_COMPONENT_STATUS_OK) {
                goto end;
        }
 
@@ -184,14 +183,13 @@ enum bt_self_component_status bt_self_component_filter_add_input_port(
                const char *name, void *user_data,
                struct bt_self_component_port_input **self_port)
 {
-       int status = BT_SELF_COMPONENT_STATUS_OK;
+       enum bt_self_component_status status;
        struct bt_port *port = NULL;
        struct bt_component *comp = (void *) self_comp;
 
        /* bt_component_add_input_port() logs details/errors */
-       port = (void *) bt_component_add_input_port(comp, name, user_data);
-       if (!port) {
-               status = BT_SELF_COMPONENT_STATUS_NOMEM;
+       status = bt_component_add_input_port(comp, name, user_data, &port);
+       if (status != BT_SELF_COMPONENT_STATUS_OK) {
                goto end;
        }
 
index 30c15609723adfa14ca096867fedc4e8443830db..76a0415225821a2dea0149a25cff08c5d89361c1 100644 (file)
@@ -117,14 +117,13 @@ enum bt_self_component_status bt_self_component_sink_add_input_port(
                const char *name, void *user_data,
                struct bt_self_component_port_input **self_port)
 {
-       int status = BT_SELF_COMPONENT_STATUS_OK;
+       enum bt_self_component_status status;
        struct bt_port *port = NULL;
        struct bt_component *comp = (void *) self_comp;
 
        /* bt_component_add_input_port() logs details/errors */
-       port = (void *) bt_component_add_input_port(comp, name, user_data);
-       if (!port) {
-               status = BT_SELF_COMPONENT_STATUS_NOMEM;
+       status = bt_component_add_input_port(comp, name, user_data, &port);
+       if (status != BT_SELF_COMPONENT_STATUS_OK) {
                goto end;
        }
 
index b638c33247b7c45c77cbc19f3e8811e6fc5ce307..585f9b72ba6454580d3d0a2279e2c71afba7ed02 100644 (file)
@@ -115,13 +115,12 @@ enum bt_self_component_status bt_self_component_source_add_output_port(
                struct bt_self_component_port_output **self_port)
 {
        struct bt_component *comp = (void *) self_comp;
-       int status = BT_SELF_COMPONENT_STATUS_OK;
+       enum bt_self_component_status status;
        struct bt_port *port = NULL;
 
        /* bt_component_add_output_port() logs details and errors */
-       port = (void *) bt_component_add_output_port(comp, name, user_data);
-       if (!port) {
-               status = BT_SELF_COMPONENT_STATUS_NOMEM;
+       status = bt_component_add_output_port(comp, name, user_data, &port);
+       if (status != BT_SELF_COMPONENT_STATUS_OK) {
                goto end;
        }
 
index 6321762f032a8bc6804da82be455903b4daaee97..641ee78b4307a9465525fbca763edb28403fca2a 100644 (file)
@@ -190,12 +190,14 @@ enum bt_component_class_type bt_component_get_class_type(
 }
 
 static
-struct bt_port *add_port(
+enum bt_self_component_status add_port(
                struct bt_component *component, GPtrArray *ports,
-               enum bt_port_type port_type, const char *name, void *user_data)
+               enum bt_port_type port_type, const char *name, void *user_data,
+               struct bt_port **port)
 {
        struct bt_port *new_port = NULL;
        struct bt_graph *graph = NULL;
+       enum bt_self_component_status status;
 
        BT_ASSERT_PRE_NON_NULL(component, "Component");
        BT_ASSERT_PRE_NON_NULL(name, "Name");
@@ -218,7 +220,8 @@ struct bt_port *add_port(
        new_port = bt_port_create(component, port_type, name, user_data);
        if (!new_port) {
                BT_LOGE_STR("Cannot create port object.");
-               goto end;
+               status = BT_SELF_COMPONENT_STATUS_NOMEM;
+               goto error;
        }
 
        /*
@@ -232,18 +235,34 @@ struct bt_port *add_port(
        /*
         * Notify the graph's creator that a new port was added.
         */
-       bt_object_get_ref(bt_component_borrow_graph(component));
        graph = bt_component_borrow_graph(component);
        if (graph) {
-               bt_graph_notify_port_added(graph, new_port);
-               BT_OBJECT_PUT_REF_AND_RESET(graph);
+               enum bt_graph_listener_status listener_status;
+
+               listener_status = bt_graph_notify_port_added(graph, new_port);
+               if (listener_status != BT_GRAPH_LISTENER_STATUS_OK) {
+                       bt_graph_make_faulty(graph);
+                       status = listener_status;
+                       goto error;
+               }
        }
 
        BT_LIB_LOGD("Created and added port to component: "
                "%![comp-]+c, %![port-]+p", component, new_port);
 
+       *port = new_port;
+       status = BT_SELF_COMPONENT_STATUS_OK;
+
+       goto end;
+error:
+       /*
+        * We need to release the reference that we would otherwise have
+        * returned to the caller.
+        */
+       BT_PORT_PUT_REF_AND_RESET(new_port);
+
 end:
-       return new_port;
+       return status;
 }
 
 BT_HIDDEN
@@ -436,25 +455,23 @@ struct bt_port_output *bt_component_borrow_output_port_by_index(
 }
 
 BT_HIDDEN
-struct bt_port_input *bt_component_add_input_port(
+enum bt_self_component_status bt_component_add_input_port(
                struct bt_component *component, const char *name,
-               void *user_data)
+               void *user_data, struct bt_port **port)
 {
        /* add_port() logs details */
-       return (void *)
-               add_port(component, component->input_ports,
-                       BT_PORT_TYPE_INPUT, name, user_data);
+       return add_port(component, component->input_ports,
+               BT_PORT_TYPE_INPUT, name, user_data, port);
 }
 
 BT_HIDDEN
-struct bt_port_output *bt_component_add_output_port(
+enum bt_self_component_status bt_component_add_output_port(
                struct bt_component *component, const char *name,
-               void *user_data)
+               void *user_data, struct bt_port **port)
 {
        /* add_port() logs details */
-       return (void *)
-               add_port(component, component->output_ports,
-                       BT_PORT_TYPE_OUTPUT, name, user_data);
+       return add_port(component, component->output_ports,
+               BT_PORT_TYPE_OUTPUT, name, user_data, port);
 }
 
 BT_HIDDEN
index 219ca277ae6a197ea4d2e604cd9730db35745ac4..7555a5435c202ccea4b855a0a65025b7ad39c295 100644 (file)
 #include <unistd.h>
 #include <glib.h>
 
-typedef void (*port_added_func_t)(const void *, const void *, void *);
+typedef enum bt_graph_listener_status (*port_added_func_t)(
+               const void *, const void *, void *);
 
-typedef void (*ports_connected_func_t)(const void *, const void *, const void *,
-               const void *, void *);
+typedef enum bt_graph_listener_status (*ports_connected_func_t)(
+               const void *, const void *, const void *, const void *, void *);
 
 typedef enum bt_self_component_status (*comp_init_method_t)(const void *,
                const void *, void *);
@@ -397,6 +398,7 @@ enum bt_graph_status bt_graph_connect_ports(
                const struct bt_connection **user_connection)
 {
        enum bt_graph_status status = BT_GRAPH_STATUS_OK;
+       enum bt_graph_listener_status listener_status;
        struct bt_connection *connection = NULL;
        struct bt_port *upstream_port = (void *) upstream_port_out;
        struct bt_port *downstream_port = (void *) downstream_port_in;
@@ -531,7 +533,12 @@ enum bt_graph_status bt_graph_connect_ports(
         * Notify the graph's creator that both ports are connected.
         */
        BT_LOGD_STR("Notifying graph's user that new component ports are connected.");
-       bt_graph_notify_ports_connected(graph, upstream_port, downstream_port);
+       listener_status = bt_graph_notify_ports_connected(graph, upstream_port, downstream_port);
+       if (listener_status != BT_GRAPH_LISTENER_STATUS_OK) {
+               status = (int) listener_status;
+               goto end;
+       }
+
        connection->notified_graph_ports_connected = true;
        BT_LIB_LOGD("Connected component ports within graph: "
                "%![graph-]+g, %![up-comp-]+c, %![down-comp-]+c, "
@@ -547,7 +554,7 @@ enum bt_graph_status bt_graph_connect_ports(
 
 end:
        if (status != BT_GRAPH_STATUS_OK) {
-               graph->config_state = BT_GRAPH_CONFIGURATION_STATE_FAULTY;
+               bt_graph_make_faulty(graph);
        }
 
        bt_object_put_ref(connection);
@@ -1051,11 +1058,13 @@ bt_graph_add_filter_sink_component_ports_connected_listener(
 }
 
 BT_HIDDEN
-void bt_graph_notify_port_added(struct bt_graph *graph, struct bt_port *port)
+enum bt_graph_listener_status bt_graph_notify_port_added(
+               struct bt_graph *graph, struct bt_port *port)
 {
        uint64_t i;
        GArray *listeners;
        struct bt_component *comp;
+       enum bt_graph_listener_status status = BT_GRAPH_LISTENER_STATUS_OK;
 
        BT_ASSERT(graph);
        BT_ASSERT(port);
@@ -1113,19 +1122,28 @@ void bt_graph_notify_port_added(struct bt_graph *graph, struct bt_port *port)
                        &g_array_index(listeners,
                                struct bt_graph_listener_port_added, i);
 
+
                BT_ASSERT(listener->func);
-               listener->func(comp, port, listener->base.data);
+               status = listener->func(comp, port, listener->base.data);
+               if (status != BT_GRAPH_LISTENER_STATUS_OK) {
+                       goto end;
+               }
        }
+
+end:
+       return status;
 }
 
 BT_HIDDEN
-void bt_graph_notify_ports_connected(struct bt_graph *graph,
-               struct bt_port *upstream_port, struct bt_port *downstream_port)
+enum bt_graph_listener_status bt_graph_notify_ports_connected(
+               struct bt_graph *graph, struct bt_port *upstream_port,
+               struct bt_port *downstream_port)
 {
        uint64_t i;
        GArray *listeners;
        struct bt_component *upstream_comp;
        struct bt_component *downstream_comp;
+       enum bt_graph_listener_status status = BT_GRAPH_LISTENER_STATUS_OK;
 
        BT_ASSERT(graph);
        BT_ASSERT(upstream_port);
@@ -1183,9 +1201,15 @@ void bt_graph_notify_ports_connected(struct bt_graph *graph,
                                struct bt_graph_listener_ports_connected, i);
 
                BT_ASSERT(listener->func);
-               listener->func(upstream_comp, downstream_comp,
+               status = listener->func(upstream_comp, downstream_comp,
                        upstream_port, downstream_port, listener->base.data);
+               if (status != BT_GRAPH_LISTENER_STATUS_OK) {
+                       goto end;
+               }
        }
+
+end:
+       return status;
 }
 
 enum bt_graph_status bt_graph_cancel(struct bt_graph *graph)
@@ -1346,7 +1370,7 @@ enum bt_graph_status add_component_with_init_method_data(
 
 end:
        if (graph_status != BT_GRAPH_STATUS_OK) {
-               graph->config_state = BT_GRAPH_CONFIGURATION_STATE_FAULTY;
+               bt_graph_make_faulty(graph);
        }
 
        bt_object_put_ref(component);
index cf73109a356a74d653cb6a2fcc7fdb4c190fb89b..bf4a8629feee67c974179ede89401dfde67a972b 100644 (file)
@@ -418,8 +418,9 @@ bt_self_component_status sink_consume(
 }
 
 static
-void graph_src_output_port_added(const bt_component_source *comp,
-               const bt_port_output *port, void *data)
+bt_graph_listener_status graph_src_output_port_added(
+               const bt_component_source *comp, const bt_port_output *port,
+               void *data)
 {
        struct event event = {
                .type = GRAPH_SRC_OUTPUT_PORT_ADDED,
@@ -430,11 +431,14 @@ void graph_src_output_port_added(const bt_component_source *comp,
        };
 
        append_event(&event);
+
+       return BT_GRAPH_LISTENER_STATUS_OK;
 }
 
 static
-void graph_sink_input_port_added(const bt_component_sink *comp,
-               const bt_port_input *port, void *data)
+bt_graph_listener_status graph_sink_input_port_added(
+               const bt_component_sink *comp, const bt_port_input *port,
+               void *data)
 {
        struct event event = {
                .type = GRAPH_SINK_INPUT_PORT_ADDED,
@@ -445,10 +449,13 @@ void graph_sink_input_port_added(const bt_component_sink *comp,
        };
 
        append_event(&event);
+
+       return BT_GRAPH_LISTENER_STATUS_OK;
 }
 
 static
-void graph_src_sink_ports_connected(const bt_component_source *upstream_comp,
+bt_graph_listener_status graph_src_sink_ports_connected(
+               const bt_component_source *upstream_comp,
                const bt_component_sink *downstream_comp,
                const bt_port_output *upstream_port,
                const bt_port_input *downstream_port, void *data)
@@ -468,6 +475,8 @@ void graph_src_sink_ports_connected(const bt_component_source *upstream_comp,
        };
 
        append_event(&event);
+
+       return BT_GRAPH_LISTENER_STATUS_OK;
 }
 
 static
This page took 0.035889 seconds and 4 git commands to generate.