From: Simon Marchi Date: Thu, 16 May 2019 16:10:18 +0000 (-0400) Subject: lib: Make graph listeners return an error status X-Git-Url: http://git.efficios.com/?p=babeltrace.git;a=commitdiff_plain;h=8cc56726828daf6e193dc131435948d2c9a2cb4e lib: Make graph listeners return an error status 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 Reviewed-on: https://review.lttng.org/c/babeltrace/+/1316 Reviewed-by: Philippe Proulx Tested-by: jenkins --- diff --git a/bindings/python/bt2/bt2/native_bt_graph.i b/bindings/python/bt2/bt2/native_bt_graph.i index c898c78e..bf6b5cdd 100644 --- a/bindings/python/bt2/bt2/native_bt_graph.i +++ b/bindings/python/bt2/bt2/native_bt_graph.i @@ -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); } diff --git a/cli/babeltrace.c b/cli/babeltrace.c index 791c6c8e..ad5f22f7 100644 --- a/cli/babeltrace.c +++ b/cli/babeltrace.c @@ -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 diff --git a/include/babeltrace/graph/component-internal.h b/include/babeltrace/graph/component-internal.h index d5555f1a..452e6c5a 100644 --- a/include/babeltrace/graph/component-internal.h +++ b/include/babeltrace/graph/component-internal.h @@ -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, diff --git a/include/babeltrace/graph/graph-internal.h b/include/babeltrace/graph/graph-internal.h index d9ae46f6..fce624fb 100644 --- a/include/babeltrace/graph/graph-internal.h +++ b/include/babeltrace/graph/graph-internal.h @@ -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 */ diff --git a/include/babeltrace/graph/graph.h b/include/babeltrace/graph/graph.h index 967bc91d..18069603 100644 --- a/include/babeltrace/graph/graph.h +++ b/include/babeltrace/graph/graph.h @@ -40,42 +40,56 @@ 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, diff --git a/lib/graph/component-filter.c b/lib/graph/component-filter.c index c1c730ca..b59543b8 100644 --- a/lib/graph/component-filter.c +++ b/lib/graph/component-filter.c @@ -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; } diff --git a/lib/graph/component-sink.c b/lib/graph/component-sink.c index 30c15609..76a04152 100644 --- a/lib/graph/component-sink.c +++ b/lib/graph/component-sink.c @@ -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; } diff --git a/lib/graph/component-source.c b/lib/graph/component-source.c index b638c332..585f9b72 100644 --- a/lib/graph/component-source.c +++ b/lib/graph/component-source.c @@ -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; } diff --git a/lib/graph/component.c b/lib/graph/component.c index 6321762f..641ee78b 100644 --- a/lib/graph/component.c +++ b/lib/graph/component.c @@ -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 diff --git a/lib/graph/graph.c b/lib/graph/graph.c index 219ca277..7555a543 100644 --- a/lib/graph/graph.c +++ b/lib/graph/graph.c @@ -47,10 +47,11 @@ #include #include -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); diff --git a/tests/lib/test_graph_topo.c b/tests/lib/test_graph_topo.c index cf73109a..bf4a8629 100644 --- a/tests/lib/test_graph_topo.c +++ b/tests/lib/test_graph_topo.c @@ -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