uint64_t i;
int64_t (*port_count_fn)(struct bt_component *);
struct bt_port *(*port_by_index_fn)(struct bt_component *, uint64_t);
- void *conn = NULL;
+ enum bt_graph_status status = BT_GRAPH_STATUS_ERROR;
BT_LOGI("Connecting upstream port to the next available downstream port: "
"upstream-port-addr=%p, upstream-port-name=\"%s\", "
cfg_conn->downstream_port_glob->str, -1ULL,
downstream_port_name, -1ULL)) {
/* We have a winner! */
- conn = bt_graph_connect_ports(ctx->graph,
- upstream_port, downstream_port);
+ status = bt_graph_connect_ports(ctx->graph,
+ upstream_port, downstream_port, NULL);
bt_put(downstream_port);
- if (!conn) {
+ switch (status) {
+ case BT_GRAPH_STATUS_OK:
+ break;
+ case BT_GRAPH_STATUS_CANCELED:
+ BT_LOGI_STR("Graph was canceled by user.");
+ status = BT_GRAPH_STATUS_OK;
+ break;
+ case BT_GRAPH_STATUS_COMPONENT_REFUSES_PORT_CONNECTION:
+ BT_LOGE("A component refused a connection to one of its ports: "
+ "upstream-comp-addr=%p, upstream-comp-name=\"%s\", "
+ "upstream-port-addr=%p, upstream-port-name=\"%s\", "
+ "downstream-comp-addr=%p, downstream-comp-name=\"%s\", "
+ "downstream-port-addr=%p, downstream-port-name=\"%s\", "
+ "conn-arg=\"%s\"",
+ upstream_comp, bt_component_get_name(upstream_comp),
+ upstream_port, bt_port_get_name(upstream_port),
+ downstream_comp, cfg_conn->downstream_comp_name->str,
+ downstream_port, downstream_port_name,
+ cfg_conn->arg->str);
+ fprintf(stderr,
+ "A component refused a connection to one of its ports (`%s` to `%s`): %s\n",
+ bt_port_get_name(upstream_port),
+ downstream_port_name,
+ cfg_conn->arg->str);
+ break;
+ default:
BT_LOGE("Cannot create connection: graph refuses to connect ports: "
"upstream-comp-addr=%p, upstream-comp-name=\"%s\", "
"upstream-port-addr=%p, upstream-port-name=\"%s\", "
bt_put(downstream_port);
}
- if (!conn) {
+ if (status != BT_GRAPH_STATUS_OK) {
BT_LOGE("Cannot create connection: cannot find a matching downstream port for upstream port: "
"upstream-port-addr=%p, upstream-port-name=\"%s\", "
"downstream-comp-name=\"%s\", conn-arg=\"%s\"",
ret = -1;
end:
- bt_put(conn);
return ret;
}
*/
#include <babeltrace/graph/graph.h>
+#include <babeltrace/graph/component-status.h>
#include <babeltrace/babeltrace-internal.h>
#include <babeltrace/object-internal.h>
+#include <stdlib.h>
#include <glib.h>
struct bt_component;
return "BT_GRAPH_STATUS_NO_SINK";
case BT_GRAPH_STATUS_ERROR:
return "BT_GRAPH_STATUS_ERROR";
+ case BT_GRAPH_STATUS_COMPONENT_REFUSES_PORT_CONNECTION:
+ return "BT_GRAPH_STATUS_COMPONENT_REFUSES_PORT_CONNECTION";
+ case BT_GRAPH_STATUS_NOMEM:
+ return "BT_GRAPH_STATUS_NOMEM";
default:
return "(unknown)";
}
}
+static inline
+enum bt_graph_status bt_graph_status_from_component_status(
+ enum bt_component_status comp_status)
+{
+ switch (comp_status) {
+ case BT_COMPONENT_STATUS_OK:
+ return BT_GRAPH_STATUS_OK;
+ case BT_COMPONENT_STATUS_END:
+ return BT_GRAPH_STATUS_END;
+ case BT_COMPONENT_STATUS_AGAIN:
+ return BT_GRAPH_STATUS_AGAIN;
+ case BT_COMPONENT_STATUS_REFUSE_PORT_CONNECTION:
+ return BT_GRAPH_STATUS_COMPONENT_REFUSES_PORT_CONNECTION;
+ case BT_COMPONENT_STATUS_ERROR:
+ return BT_GRAPH_STATUS_ERROR;
+ case BT_COMPONENT_STATUS_UNSUPPORTED:
+ return BT_GRAPH_STATUS_ERROR;
+ case BT_COMPONENT_STATUS_INVALID:
+ return BT_GRAPH_STATUS_INVALID;
+ case BT_COMPONENT_STATUS_NOMEM:
+ return BT_GRAPH_STATUS_NOMEM;
+ case BT_COMPONENT_STATUS_NOT_FOUND:
+ return BT_GRAPH_STATUS_ERROR;
+ default:
+#ifdef BT_LOGF
+ BT_LOGF("Unknown component status: status=%d", comp_status);
+#endif
+ abort();
+ }
+}
+
#endif /* BABELTRACE_COMPONENT_COMPONENT_GRAPH_INTERNAL_H */
struct bt_connection;
enum bt_graph_status {
+ BT_GRAPH_STATUS_COMPONENT_REFUSES_PORT_CONNECTION = 111,
/** Canceled. */
BT_GRAPH_STATUS_CANCELED = 125,
/** No sink can consume at the moment. */
BT_GRAPH_STATUS_NO_SINK = -6,
/** General error. */
BT_GRAPH_STATUS_ERROR = -1,
+ BT_GRAPH_STATUS_NOMEM = -12,
};
typedef void (*bt_graph_port_added_listener)(struct bt_port *port,
* Creates a connection between two components using the two ports specified
* and adds the connection and components (if not already added) to the graph.
*/
-extern struct bt_connection *bt_graph_connect_ports(struct bt_graph *graph,
- struct bt_port *upstream,
- struct bt_port *downstream);
+extern enum bt_graph_status bt_graph_connect_ports(struct bt_graph *graph,
+ struct bt_port *upstream, struct bt_port *downstream,
+ struct bt_connection **connection);
/**
* Run graph to completion or until a single sink is left and "AGAIN" is received.
goto end;
}
-struct bt_connection *bt_graph_connect_ports(struct bt_graph *graph,
- struct bt_port *upstream_port,
- struct bt_port *downstream_port)
+enum bt_graph_status bt_graph_connect_ports(struct bt_graph *graph,
+ struct bt_port *upstream_port, struct bt_port *downstream_port,
+ struct bt_connection **user_connection)
{
+ enum bt_graph_status status = BT_GRAPH_STATUS_OK;
struct bt_connection *connection = NULL;
struct bt_graph *upstream_graph = NULL;
struct bt_graph *downstream_graph = NULL;
if (!graph) {
BT_LOGW_STR("Invalid parameter: graph is NULL.");
+ status = BT_GRAPH_STATUS_INVALID;
goto end;
}
if (!upstream_port) {
BT_LOGW_STR("Invalid parameter: upstream port is NULL.");
+ status = BT_GRAPH_STATUS_INVALID;
goto end;
}
if (!downstream_port) {
BT_LOGW_STR("Invalid parameter: downstream port is NULL.");
+ status = BT_GRAPH_STATUS_INVALID;
goto end;
}
if (graph->canceled) {
BT_LOGW_STR("Invalid parameter: graph is canceled.");
+ status = BT_GRAPH_STATUS_CANCELED;
goto end;
}
/* Ensure appropriate types for upstream and downstream ports. */
if (bt_port_get_type(upstream_port) != BT_PORT_TYPE_OUTPUT) {
BT_LOGW_STR("Invalid parameter: upstream port is not an output port.");
+ status = BT_GRAPH_STATUS_INVALID;
goto end;
}
if (bt_port_get_type(downstream_port) != BT_PORT_TYPE_INPUT) {
BT_LOGW_STR("Invalid parameter: downstream port is not an input port.");
+ status = BT_GRAPH_STATUS_INVALID;
goto end;
}
/* Ensure that both ports are currently unconnected. */
if (bt_port_is_connected(upstream_port)) {
BT_LOGW_STR("Invalid parameter: upstream port is already connected.");
+ status = BT_GRAPH_STATUS_INVALID;
goto end;
}
if (bt_port_is_connected(downstream_port)) {
BT_LOGW_STR("Invalid parameter: downstream port is already connected.");
+ status = BT_GRAPH_STATUS_INVALID;
goto end;
}
upstream_component = bt_port_get_component(upstream_port);
if (!upstream_component) {
BT_LOGW_STR("Invalid parameter: upstream port is loose (does not belong to a component)");
+ status = BT_GRAPH_STATUS_INVALID;
goto end;
}
downstream_component = bt_port_get_component(downstream_port);
if (!downstream_component) {
BT_LOGW_STR("Invalid parameter: downstream port is loose (does not belong to a component)");
+ status = BT_GRAPH_STATUS_INVALID;
goto end;
}
if (upstream_graph && (graph != upstream_graph)) {
BT_LOGW("Invalid parameter: upstream port's component is already part of another graph: "
"other-graph-addr=%p", upstream_graph);
- goto error;
+ status = BT_GRAPH_STATUS_ALREADY_IN_A_GRAPH;
+ goto end;
}
upstream_was_already_in_graph = (graph == upstream_graph);
downstream_graph = bt_component_get_graph(downstream_component);
if (downstream_graph && (graph != downstream_graph)) {
BT_LOGW("Invalid parameter: downstream port's component is already part of another graph: "
"other-graph-addr=%p", downstream_graph);
- goto error;
+ status = BT_GRAPH_STATUS_ALREADY_IN_A_GRAPH;
+ goto end;
}
downstream_was_already_in_graph = (graph == downstream_graph);
"status=%s", bt_component_status_string(component_status));
}
- goto error;
+ status = bt_graph_status_from_component_status(
+ component_status);
+ goto end;
}
BT_LOGD_STR("Asking downstream component to accept the connection.");
"status=%s", bt_component_status_string(component_status));
}
- goto error;
+ status = bt_graph_status_from_component_status(
+ component_status);
+ goto end;
}
BT_LOGD_STR("Creating connection.");
downstream_port);
if (!connection) {
BT_LOGW("Cannot create connection object.");
- goto error;
+ status = BT_GRAPH_STATUS_NOMEM;
+ goto end;
}
BT_LOGD("Connection object created: conn-addr=%p", connection);
upstream_port, bt_port_get_name(upstream_port),
downstream_port, bt_port_get_name(downstream_port));
+ if (user_connection) {
+ BT_MOVE(*user_connection, connection);
+ }
+
end:
bt_put(upstream_graph);
bt_put(downstream_graph);
bt_put(upstream_component);
bt_put(downstream_component);
- return connection;
-
-error:
- BT_PUT(upstream_component);
- BT_PUT(downstream_component);
- goto end;
+ bt_put(connection);
+ return status;
}
enum bt_graph_status bt_graph_consume(struct bt_graph *graph)
struct bt_port *upstream_port;
struct bt_port *downstream_port;
struct bt_graph *graph;
- void *conn;
enum bt_graph_status graph_status = BT_GRAPH_STATUS_OK;
clear_test_events();
assert(upstream_port);
downstream_port = bt_component_sink_get_input_port_by_name(sink_comp, "in");
assert(downstream_port);
- conn = bt_graph_connect_ports(graph, upstream_port, downstream_port);
- assert(conn);
- bt_put(conn);
+ graph_status = bt_graph_connect_ports(graph, upstream_port,
+ downstream_port, NULL);
bt_put(upstream_port);
bt_put(downstream_port);
struct bt_port *sink_def_port;
struct bt_connection *conn;
struct event event;
+ enum bt_graph_status status;
size_t src_accept_port_connection_pos;
size_t sink_accept_port_connection_pos;
size_t src_port_connected_pos;
assert(src_def_port);
sink_def_port = bt_component_sink_get_input_port_by_name(sink, "in");
assert(sink_def_port);
- conn = bt_graph_connect_ports(graph, src_def_port, sink_def_port);
+ status = bt_graph_connect_ports(graph, src_def_port, sink_def_port,
+ &conn);
+ assert(status == 0);
assert(conn);
/* We're supposed to have 5 events so far */
struct bt_port *sink_def_port;
struct bt_connection *conn;
struct event event;
+ enum bt_graph_status status;
size_t src_accept_port_connection_pos;
size_t sink_accept_port_connection_pos;
size_t src_port_connected_pos;
assert(src_def_port);
sink_def_port = bt_component_sink_get_input_port_by_name(sink, "in");
assert(sink_def_port);
- conn = bt_graph_connect_ports(graph, src_def_port, sink_def_port);
- assert(conn);
+ status = bt_graph_connect_ports(graph, src_def_port, sink_def_port,
+ &conn);
+ assert(status == 0);
/* We're supposed to have 5 events so far */
ok(events->len == 5, "we have the expected number of events (before consume)");
struct bt_port *src_hello_port;
struct bt_connection *conn;
struct event event;
+ enum bt_graph_status status;
size_t src_accept_port_connection_pos;
size_t sink_accept_port_connection_pos;
size_t src_port_connected_pos;
assert(src_def_port);
sink_def_port = bt_component_sink_get_input_port_by_name(sink, "in");
assert(sink_def_port);
- conn = bt_graph_connect_ports(graph, src_def_port, sink_def_port);
- assert(conn);
+ status = bt_graph_connect_ports(graph, src_def_port, sink_def_port,
+ &conn);
+ assert(status == 0);
src_hello_port = bt_component_source_get_output_port_by_name(src,
"hello");
assert(src_hello_port);
struct bt_port *sink_def_port;
struct bt_connection *conn;
struct event event;
+ enum bt_graph_status status;
size_t src_accept_port_connection_pos;
size_t sink_accept_port_connection_pos;
size_t src_port_connected_pos;
assert(src_def_port);
sink_def_port = bt_component_sink_get_input_port_by_name(sink, "in");
assert(sink_def_port);
- conn = bt_graph_connect_ports(graph, src_def_port, sink_def_port);
- assert(conn);
+ status = bt_graph_connect_ports(graph, src_def_port, sink_def_port,
+ &conn);
+ assert(status == 0);
/* We're supposed to have 5 events */
ok(events->len == 5, "we have the expected number of events");
struct bt_graph *graph;
int64_t i;
int64_t count;
- void *conn;
enum bt_graph_status graph_status = BT_GRAPH_STATUS_OK;
clear_test_events();
downstream_port = bt_component_filter_get_input_port_by_index(
muxer_comp, i);
assert(downstream_port);
- conn = bt_graph_connect_ports(graph,
- upstream_port, downstream_port);
- assert(conn);
- bt_put(conn);
+ graph_status = bt_graph_connect_ports(graph,
+ upstream_port, downstream_port, NULL);
+ assert(graph_status == 0);
bt_put(upstream_port);
bt_put(downstream_port);
}
assert(upstream_port);
downstream_port = bt_component_sink_get_input_port_by_name(sink_comp, "in");
assert(downstream_port);
- conn = bt_graph_connect_ports(graph, upstream_port, downstream_port);
- assert(conn);
- bt_put(conn);
+ graph_status = bt_graph_connect_ports(graph, upstream_port,
+ downstream_port, NULL);
+ assert(graph_status == 0);
bt_put(upstream_port);
bt_put(downstream_port);
struct bt_component *muxer_comp)
{
struct bt_port *avail_muxer_port = NULL;
- void *conn;
int64_t i;
int64_t count;
+ enum bt_graph_status graph_status;
count = bt_component_filter_get_input_port_count(muxer_comp);
assert(count >= 0);
}
}
- conn = bt_graph_connect_ports(graph, source_port, avail_muxer_port);
- assert(conn);
- bt_put(conn);
+ graph_status = bt_graph_connect_ports(graph, source_port,
+ avail_muxer_port, NULL);
+ assert(graph_status == 0);
bt_put(avail_muxer_port);
}
struct bt_graph *graph;
int64_t i;
int64_t count;
- void *conn;
int ret;
enum bt_graph_status graph_status = BT_GRAPH_STATUS_OK;
struct graph_listener_data graph_listener_data;
assert(upstream_port);
downstream_port = bt_component_sink_get_input_port_by_name(sink_comp, "in");
assert(downstream_port);
- conn = bt_graph_connect_ports(graph, upstream_port, downstream_port);
- assert(conn);
- bt_put(conn);
+ graph_status = bt_graph_connect_ports(graph, upstream_port,
+ downstream_port, NULL);
+ assert(graph_status == 0);
bt_put(upstream_port);
bt_put(downstream_port);
struct bt_graph *graph;
int64_t i;
int64_t count;
- void *conn;
int ret;
enum bt_graph_status graph_status = BT_GRAPH_STATUS_OK;
struct graph_listener_data graph_listener_data;
assert(upstream_port);
downstream_port = bt_component_sink_get_input_port_by_name(sink_comp, "in");
assert(downstream_port);
- conn = bt_graph_connect_ports(graph, upstream_port, downstream_port);
- assert(conn);
- bt_put(conn);
+ graph_status = bt_graph_connect_ports(graph, upstream_port,
+ downstream_port, NULL);
+ assert(graph_status == 0);
bt_put(upstream_port);
bt_put(downstream_port);