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
-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);
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);
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);
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);
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);
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);
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);
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,
const bt_component_filter *filter_component,
const bt_component_sink *sink_component,
const bt_port_output *upstream_port,
Py_DECREF(py_callable);
}
Py_DECREF(py_callable);
}
+static bt_graph_listener_status
port_added_listener(
const void *component,
swig_type_info *component_swig_type,
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,
const void *port,
swig_type_info *port_swig_type,
bt_port_type port_type,
PyObject *py_component_ptr = NULL;
PyObject *py_port_ptr = NULL;
PyObject *py_res = NULL;
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) {
py_component_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(component), component_swig_type, 0);
if (!py_component_ptr) {
Py_XDECREF(py_res);
Py_XDECREF(py_port_ptr);
Py_XDECREF(py_component_ptr);
Py_XDECREF(py_res);
Py_XDECREF(py_port_ptr);
Py_XDECREF(py_component_ptr);
+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)
{
source_component_output_port_added_listener(const bt_component_source *component_source,
const bt_port_output *port_output, void *py_callable)
{
+ 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);
}
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 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)
{
filter_component_input_port_added_listener(const bt_component_filter *component_filter,
const bt_port_input *port_input, void *py_callable)
{
+ 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);
}
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 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)
{
filter_component_output_port_added_listener(const bt_component_filter *component_filter,
const bt_port_output *port_output, void *py_callable)
{
+ 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);
}
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 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)
{
sink_component_input_port_added_listener(const bt_component_sink *component_sink,
const bt_port_input *port_input, void *py_callable)
{
+ 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);
}
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);
}
return py_listener_ids;
}
return py_listener_ids;
}
+static bt_graph_listener_status
ports_connected_listener(const bt_port_output *upstream_port,
const bt_port_input *downstream_port,
void *py_callable)
ports_connected_listener(const bt_port_output *upstream_port,
const bt_port_input *downstream_port,
void *py_callable)
PyObject *py_upstream_port_ptr = NULL;
PyObject *py_downstream_port_ptr = NULL;
PyObject *py_res = NULL;
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);
py_upstream_port_ptr = SWIG_NewPointerObj(
SWIG_as_voidptr(upstream_port), SWIGTYPE_p_bt_port_output, 0);
Py_DECREF(py_upstream_port_ptr);
Py_DECREF(py_downstream_port_ptr);
Py_XDECREF(py_res);
Py_DECREF(py_upstream_port_ptr);
Py_DECREF(py_downstream_port_ptr);
Py_XDECREF(py_res);
+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)
{
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 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)
{
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 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)
{
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 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)
{
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);
-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);
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, "
comp = bt_port_borrow_component_const(port);
BT_LOGI("Port added to a graph's component: comp-addr=%p, "
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");
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");
+ ret = BT_GRAPH_LISTENER_STATUS_ERROR;
+ goto end;
-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)
{
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);
-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)
{
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);
struct bt_component *comp, const char *name);
BT_HIDDEN
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,
struct bt_component *component, const char *name,
+ void *user_data, struct bt_port **port);
-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,
struct bt_component *component, const char *name,
+ void *user_data, struct bt_port **port);
BT_HIDDEN
void bt_component_remove_port(struct bt_component *component,
BT_HIDDEN
void bt_component_remove_port(struct bt_component *component,
struct bt_component_sink *sink);
BT_HIDDEN
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);
-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,
BT_HIDDEN
void bt_graph_remove_connection(struct bt_graph *graph,
+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 */
#endif /* BABELTRACE_GRAPH_GRAPH_INTERNAL_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);
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);
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);
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);
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);
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);
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);
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,
const bt_component_filter *filter_component,
const bt_component_sink *sink_component,
const bt_port_output *upstream_port,
struct bt_self_component_port_output **self_port)
{
struct bt_component *comp = (void *) self_comp;
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 */
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) {
const char *name, void *user_data,
struct bt_self_component_port_input **self_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 */
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) {
const char *name, void *user_data,
struct bt_self_component_port_input **self_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 */
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) {
struct bt_self_component_port_output **self_port)
{
struct bt_component *comp = (void *) self_comp;
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 */
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) {
-struct bt_port *add_port(
+enum bt_self_component_status add_port(
struct bt_component *component, GPtrArray *ports,
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;
{
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");
BT_ASSERT_PRE_NON_NULL(component, "Component");
BT_ASSERT_PRE_NON_NULL(name, "Name");
new_port = bt_port_create(component, port_type, name, user_data);
if (!new_port) {
BT_LOGE_STR("Cannot create port object.");
new_port = bt_port_create(component, port_type, name, user_data);
if (!new_port) {
BT_LOGE_STR("Cannot create port object.");
+ status = BT_SELF_COMPONENT_STATUS_NOMEM;
+ goto error;
/*
* Notify the graph's creator that a new port was added.
*/
/*
* 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) {
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);
}
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);
+
-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,
struct bt_component *component, const char *name,
+ void *user_data, struct bt_port **port)
{
/* add_port() logs details */
{
/* 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);
-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,
struct bt_component *component, const char *name,
+ void *user_data, struct bt_port **port)
{
/* add_port() logs details */
{
/* 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);
#include <unistd.h>
#include <glib.h>
#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 *);
typedef enum bt_self_component_status (*comp_init_method_t)(const void *,
const void *, void *);
const struct bt_connection **user_connection)
{
enum bt_graph_status status = BT_GRAPH_STATUS_OK;
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;
struct bt_connection *connection = NULL;
struct bt_port *upstream_port = (void *) upstream_port_out;
struct bt_port *downstream_port = (void *) downstream_port_in;
* Notify the graph's creator that both ports are connected.
*/
BT_LOGD_STR("Notifying graph's user that new component ports are connected.");
* 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, "
connection->notified_graph_ports_connected = true;
BT_LIB_LOGD("Connected component ports within graph: "
"%![graph-]+g, %![up-comp-]+c, %![down-comp-]+c, "
end:
if (status != BT_GRAPH_STATUS_OK) {
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);
}
bt_object_put_ref(connection);
-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;
{
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);
BT_ASSERT(graph);
BT_ASSERT(port);
&g_array_index(listeners,
struct bt_graph_listener_port_added, i);
&g_array_index(listeners,
struct bt_graph_listener_port_added, i);
BT_ASSERT(listener->func);
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;
+ }
-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;
{
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);
BT_ASSERT(graph);
BT_ASSERT(upstream_port);
struct bt_graph_listener_ports_connected, i);
BT_ASSERT(listener->func);
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);
upstream_port, downstream_port, listener->base.data);
+ if (status != BT_GRAPH_LISTENER_STATUS_OK) {
+ goto end;
+ }
}
enum bt_graph_status bt_graph_cancel(struct bt_graph *graph)
}
enum bt_graph_status bt_graph_cancel(struct bt_graph *graph)
end:
if (graph_status != BT_GRAPH_STATUS_OK) {
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);
}
bt_object_put_ref(component);
-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,
{
struct event event = {
.type = GRAPH_SRC_OUTPUT_PORT_ADDED,
+
+ return BT_GRAPH_LISTENER_STATUS_OK;
-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,
{
struct event event = {
.type = GRAPH_SINK_INPUT_PORT_ADDED,
+
+ return BT_GRAPH_LISTENER_STATUS_OK;
-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)
const bt_component_sink *downstream_comp,
const bt_port_output *upstream_port,
const bt_port_input *downstream_port, void *data)
+
+ return BT_GRAPH_LISTENER_STATUS_OK;