X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=lib%2Fgraph%2Fgraph.c;h=f7b02a10bece15a7914d8612e362f058328bcc6e;hb=68b66a256a54d32992dfefeaad11eea88b7df234;hp=3b48c561b685718aab9702040d84b3f2cd15a3c2;hpb=d6e69534ef08a2dd8bff9eb5af1eab63736b3d31;p=babeltrace.git diff --git a/lib/graph/graph.c b/lib/graph/graph.c index 3b48c561..f7b02a10 100644 --- a/lib/graph/graph.c +++ b/lib/graph/graph.c @@ -22,41 +22,37 @@ */ #define BT_LOG_TAG "GRAPH" -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include -typedef void (*port_added_func_t)(const void *, const void *, void *); - -typedef void (*port_removed_func_t)(const void *, const void *, void *); - -typedef void (*ports_connected_func_t)(const void *, const void *, const void *, - const void *, void *); - -typedef void (*ports_disconnected_func_t)(const void *, const void *, +typedef enum bt_graph_listener_status (*port_added_func_t)( 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 *); @@ -70,21 +66,11 @@ struct bt_graph_listener_port_added { port_added_func_t func; }; -struct bt_graph_listener_port_removed { - struct bt_graph_listener base; - port_removed_func_t func; -}; - struct bt_graph_listener_ports_connected { struct bt_graph_listener base; ports_connected_func_t func; }; -struct bt_graph_listener_ports_disconnected { - struct bt_graph_listener base; - ports_disconnected_func_t func; -}; - #define INIT_LISTENERS_ARRAY(_type, _listeners) \ do { \ _listeners = g_array_new(FALSE, TRUE, sizeof(_type)); \ @@ -97,6 +83,9 @@ struct bt_graph_listener_ports_disconnected { do { \ size_t i; \ \ + if (!_listeners) { \ + break; \ + } \ for (i = 0; i < (_listeners)->len; i++) { \ _type *listener = \ &g_array_index((_listeners), _type, i); \ @@ -118,11 +107,11 @@ void destroy_graph(struct bt_object *obj) * in this situation: * * 1. We put and destroy a connection. - * 2. This connection's destructor finalizes its active - * message iterators. - * 3. A message iterator's finalization function gets a - * new reference on its component (reference count goes from - * 0 to 1). + * 2. This connection's destructor finalizes its active message + * iterators. + * 3. A message iterator's finalization function gets a new + * reference on its component (reference count goes from 0 to + * 1). * 4. Since this component's reference count goes to 1, it takes * a reference on its parent (this graph). This graph's * reference count goes from 0 to 1. @@ -131,8 +120,8 @@ void destroy_graph(struct bt_object *obj) * 6. Since this component's reference count goes from 1 to 0, * it puts its parent (this graph). This graph's reference * count goes from 1 to 0. - * 7. Since this graph's reference count goes from 1 to 0, - * its destructor is called (this function). + * 7. Since this graph's reference count goes from 1 to 0, its + * destructor is called (this function). * * With the incrementation below, the graph's reference count at * step 4 goes from 1 to 2, and from 2 to 1 at step 6. This @@ -156,26 +145,14 @@ void destroy_graph(struct bt_object *obj) graph->listeners.filter_input_port_added); CALL_REMOVE_LISTENERS(struct bt_graph_listener_port_added, graph->listeners.sink_input_port_added); - CALL_REMOVE_LISTENERS(struct bt_graph_listener_port_removed, - graph->listeners.source_output_port_removed); - CALL_REMOVE_LISTENERS(struct bt_graph_listener_port_removed, - graph->listeners.filter_output_port_removed); - CALL_REMOVE_LISTENERS(struct bt_graph_listener_port_removed, - graph->listeners.filter_input_port_removed); - CALL_REMOVE_LISTENERS(struct bt_graph_listener_port_removed, - graph->listeners.sink_input_port_removed); CALL_REMOVE_LISTENERS(struct bt_graph_listener_ports_connected, graph->listeners.source_filter_ports_connected); + CALL_REMOVE_LISTENERS(struct bt_graph_listener_ports_connected, + graph->listeners.filter_filter_ports_connected); CALL_REMOVE_LISTENERS(struct bt_graph_listener_ports_connected, graph->listeners.source_sink_ports_connected); CALL_REMOVE_LISTENERS(struct bt_graph_listener_ports_connected, graph->listeners.filter_sink_ports_connected); - CALL_REMOVE_LISTENERS(struct bt_graph_listener_ports_disconnected, - graph->listeners.source_filter_ports_disconnected); - CALL_REMOVE_LISTENERS(struct bt_graph_listener_ports_disconnected, - graph->listeners.source_sink_ports_disconnected); - CALL_REMOVE_LISTENERS(struct bt_graph_listener_ports_disconnected, - graph->listeners.filter_sink_ports_disconnected); if (graph->messages) { g_ptr_array_free(graph->messages, TRUE); @@ -219,32 +196,18 @@ void destroy_graph(struct bt_object *obj) graph->listeners.sink_input_port_added = NULL; } - if (graph->listeners.source_output_port_removed) { - g_array_free(graph->listeners.source_output_port_removed, TRUE); - graph->listeners.source_output_port_removed = NULL; - } - - if (graph->listeners.filter_output_port_removed) { - g_array_free(graph->listeners.filter_output_port_removed, TRUE); - graph->listeners.filter_output_port_removed = NULL; - } - - if (graph->listeners.filter_input_port_removed) { - g_array_free(graph->listeners.filter_input_port_removed, TRUE); - graph->listeners.filter_input_port_removed = NULL; - } - - if (graph->listeners.sink_input_port_removed) { - g_array_free(graph->listeners.sink_input_port_removed, TRUE); - graph->listeners.sink_input_port_removed = NULL; - } - if (graph->listeners.source_filter_ports_connected) { g_array_free(graph->listeners.source_filter_ports_connected, TRUE); graph->listeners.source_filter_ports_connected = NULL; } + if (graph->listeners.filter_filter_ports_connected) { + g_array_free(graph->listeners.filter_filter_ports_connected, + TRUE); + graph->listeners.filter_filter_ports_connected = NULL; + } + if (graph->listeners.source_sink_ports_connected) { g_array_free(graph->listeners.source_sink_ports_connected, TRUE); @@ -257,24 +220,6 @@ void destroy_graph(struct bt_object *obj) graph->listeners.filter_sink_ports_connected = NULL; } - if (graph->listeners.source_filter_ports_disconnected) { - g_array_free(graph->listeners.source_filter_ports_disconnected, - TRUE); - graph->listeners.source_filter_ports_disconnected = NULL; - } - - if (graph->listeners.source_sink_ports_disconnected) { - g_array_free(graph->listeners.source_sink_ports_disconnected, - TRUE); - graph->listeners.source_sink_ports_disconnected = NULL; - } - - if (graph->listeners.filter_sink_ports_disconnected) { - g_array_free(graph->listeners.filter_sink_ports_disconnected, - TRUE); - graph->listeners.filter_sink_ports_disconnected = NULL; - } - bt_object_pool_finalize(&graph->event_msg_pool); bt_object_pool_finalize(&graph->packet_begin_msg_pool); bt_object_pool_finalize(&graph->packet_end_msg_pool); @@ -292,14 +237,14 @@ static void destroy_message_packet_begin(struct bt_message *msg, struct bt_graph *graph) { - bt_message_packet_beginning_destroy(msg); + bt_message_packet_destroy(msg); } static void destroy_message_packet_end(struct bt_message *msg, struct bt_graph *graph) { - bt_message_packet_end_destroy(msg); + bt_message_packet_destroy(msg); } static @@ -372,38 +317,6 @@ struct bt_graph *bt_graph_create(void) goto error; } - INIT_LISTENERS_ARRAY(struct bt_graph_listener_port_removed, - graph->listeners.source_output_port_removed); - - if (!graph->listeners.source_output_port_removed) { - ret = -1; - goto error; - } - - INIT_LISTENERS_ARRAY(struct bt_graph_listener_port_removed, - graph->listeners.filter_output_port_removed); - - if (!graph->listeners.filter_output_port_removed) { - ret = -1; - goto error; - } - - INIT_LISTENERS_ARRAY(struct bt_graph_listener_port_removed, - graph->listeners.filter_input_port_removed); - - if (!graph->listeners.filter_input_port_removed) { - ret = -1; - goto error; - } - - INIT_LISTENERS_ARRAY(struct bt_graph_listener_port_removed, - graph->listeners.sink_input_port_removed); - - if (!graph->listeners.sink_input_port_removed) { - ret = -1; - goto error; - } - INIT_LISTENERS_ARRAY(struct bt_graph_listener_ports_connected, graph->listeners.source_filter_ports_connected); @@ -421,33 +334,17 @@ struct bt_graph *bt_graph_create(void) } INIT_LISTENERS_ARRAY(struct bt_graph_listener_ports_connected, - graph->listeners.filter_sink_ports_connected); - - if (!graph->listeners.filter_sink_ports_connected) { - ret = -1; - goto error; - } - - INIT_LISTENERS_ARRAY(struct bt_graph_listener_ports_disconnected, - graph->listeners.source_filter_ports_disconnected); - - if (!graph->listeners.source_filter_ports_disconnected) { - ret = -1; - goto error; - } + graph->listeners.filter_filter_ports_connected); - INIT_LISTENERS_ARRAY(struct bt_graph_listener_ports_disconnected, - graph->listeners.source_sink_ports_disconnected); - - if (!graph->listeners.source_sink_ports_disconnected) { + if (!graph->listeners.filter_filter_ports_connected) { ret = -1; goto error; } - INIT_LISTENERS_ARRAY(struct bt_graph_listener_ports_disconnected, - graph->listeners.filter_sink_ports_disconnected); + INIT_LISTENERS_ARRAY(struct bt_graph_listener_ports_connected, + graph->listeners.filter_sink_ports_connected); - if (!graph->listeners.filter_sink_ports_disconnected) { + if (!graph->listeners.filter_sink_ports_connected) { ret = -1; goto error; } @@ -501,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; @@ -513,6 +411,9 @@ enum bt_graph_status bt_graph_connect_ports( BT_ASSERT_PRE_NON_NULL(upstream_port, "Upstream port"); BT_ASSERT_PRE_NON_NULL(downstream_port, "Downstream port port"); BT_ASSERT_PRE(!graph->canceled, "Graph is canceled: %!+g", graph); + BT_ASSERT_PRE( + graph->config_state == BT_GRAPH_CONFIGURATION_STATE_CONFIGURING, + "Graph is not in the \"configuring\" state: %!+g", graph); BT_ASSERT_PRE(!bt_port_is_connected(upstream_port), "Upstream port is already connected: %!+p", upstream_port); BT_ASSERT_PRE(!bt_port_is_connected(downstream_port), @@ -608,7 +509,7 @@ enum bt_graph_status bt_graph_connect_ports( goto end; } - connection->msgied_upstream_port_connected = true; + connection->notified_upstream_port_connected = true; BT_LIB_LOGD("Notifying downstream component that its port is connected: " "%![comp-]+c, %![port-]+p", downstream_component, downstream_port); @@ -626,14 +527,19 @@ enum bt_graph_status bt_graph_connect_ports( goto end; } - connection->msgied_downstream_port_connected = true; + connection->notified_downstream_port_connected = true; /* * 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); - connection->msgied_graph_ports_connected = true; + 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, " "%![up-port-]+p, %![down-port-]+p", @@ -647,6 +553,10 @@ enum bt_graph_status bt_graph_connect_ports( } end: + if (status != BT_GRAPH_STATUS_OK) { + bt_graph_make_faulty(graph); + } + bt_object_put_ref(connection); (void) init_can_consume; bt_graph_set_can_consume(graph, init_can_consume); @@ -776,8 +686,7 @@ end: return status; } -enum bt_graph_status bt_graph_consume( - struct bt_graph *graph) +enum bt_graph_status bt_graph_consume(struct bt_graph *graph) { enum bt_graph_status status; @@ -785,21 +694,39 @@ enum bt_graph_status bt_graph_consume( BT_ASSERT_PRE(!graph->canceled, "Graph is canceled: %!+g", graph); BT_ASSERT_PRE(graph->can_consume, "Cannot consume graph in its current state: %!+g", graph); - bt_graph_set_can_consume(graph, BT_FALSE); + BT_ASSERT_PRE(graph->config_state != BT_GRAPH_CONFIGURATION_STATE_FAULTY, + "Graph is in a faulty state: %!+g", graph); + bt_graph_set_can_consume(graph, false); + status = bt_graph_configure(graph); + if (unlikely(status)) { + /* bt_graph_configure() logs errors */ + goto end; + } + status = consume_no_check(graph); - bt_graph_set_can_consume(graph, BT_TRUE); + bt_graph_set_can_consume(graph, true); + +end: return status; } enum bt_graph_status bt_graph_run(struct bt_graph *graph) { - enum bt_graph_status status = BT_GRAPH_STATUS_OK; + enum bt_graph_status status; BT_ASSERT_PRE_NON_NULL(graph, "Graph"); BT_ASSERT_PRE(!graph->canceled, "Graph is canceled: %!+g", graph); BT_ASSERT_PRE(graph->can_consume, "Cannot consume graph in its current state: %!+g", graph); - bt_graph_set_can_consume(graph, BT_FALSE); + BT_ASSERT_PRE(graph->config_state != BT_GRAPH_CONFIGURATION_STATE_FAULTY, + "Graph is in a faulty state: %!+g", graph); + bt_graph_set_can_consume(graph, false); + status = bt_graph_configure(graph); + if (unlikely(status)) { + /* bt_graph_configure() logs errors */ + goto end; + } + BT_LIB_LOGV("Running graph: %!+g", graph); do { @@ -832,8 +759,6 @@ enum bt_graph_status bt_graph_run(struct bt_graph *graph) if (graph->sinks_to_consume->length > 1) { status = BT_GRAPH_STATUS_OK; } - } else if (status == BT_GRAPH_STATUS_NO_SINK) { - goto end; } } while (status == BT_GRAPH_STATUS_OK); @@ -844,7 +769,7 @@ enum bt_graph_status bt_graph_run(struct bt_graph *graph) end: BT_LIB_LOGV("Graph ran: %![graph-]+g, status=%s", graph, bt_graph_status_string(status)); - bt_graph_set_can_consume(graph, BT_TRUE); + bt_graph_set_can_consume(graph, true); return status; } @@ -988,146 +913,6 @@ bt_graph_add_sink_component_input_port_added_listener( return BT_GRAPH_STATUS_OK; } -enum bt_graph_status -bt_graph_add_source_component_output_port_removed_listener( - struct bt_graph *graph, - bt_graph_source_component_output_port_removed_listener_func func, - bt_graph_listener_removed_func listener_removed, void *data, - int *out_listener_id) -{ - struct bt_graph_listener_port_removed listener = { - .base = { - .removed = listener_removed, - .data = data, - }, - .func = (port_removed_func_t) func, - }; - int listener_id; - - BT_ASSERT_PRE_NON_NULL(graph, "Graph"); - BT_ASSERT_PRE_NON_NULL(func, "Listener"); - BT_ASSERT_PRE_NON_NULL(func, "\"Listener removed\" listener"); - BT_ASSERT_PRE(!graph->in_remove_listener, - "Graph currently executing a \"listener removed\" listener: " - "%!+g", graph); - g_array_append_val(graph->listeners.source_output_port_removed, listener); - listener_id = graph->listeners.source_output_port_removed->len - 1; - BT_LIB_LOGV("Added \"source component output port removed\" listener to graph: " - "%![graph-]+g, listener-addr=%p, id=%d", graph, listener, - listener_id); - - if (listener_id) { - *out_listener_id = listener_id; - } - - return BT_GRAPH_STATUS_OK; -} - -enum bt_graph_status -bt_graph_add_filter_component_output_port_removed_listener( - struct bt_graph *graph, - bt_graph_filter_component_output_port_removed_listener_func func, - bt_graph_listener_removed_func listener_removed, void *data, - int *out_listener_id) -{ - struct bt_graph_listener_port_removed listener = { - .base = { - .removed = listener_removed, - .data = data, - }, - .func = (port_removed_func_t) func, - }; - int listener_id; - - BT_ASSERT_PRE_NON_NULL(graph, "Graph"); - BT_ASSERT_PRE_NON_NULL(func, "Listener"); - BT_ASSERT_PRE_NON_NULL(func, "\"Listener removed\" listener"); - BT_ASSERT_PRE(!graph->in_remove_listener, - "Graph currently executing a \"listener removed\" listener: " - "%!+g", graph); - g_array_append_val(graph->listeners.filter_output_port_removed, listener); - listener_id = graph->listeners.filter_output_port_removed->len - 1; - BT_LIB_LOGV("Added \"filter component output port removed\" listener to graph: " - "%![graph-]+g, listener-addr=%p, id=%d", graph, listener, - listener_id); - - if (listener_id) { - *out_listener_id = listener_id; - } - - return BT_GRAPH_STATUS_OK; -} - -enum bt_graph_status -bt_graph_add_filter_component_input_port_removed_listener( - struct bt_graph *graph, - bt_graph_filter_component_input_port_removed_listener_func func, - bt_graph_listener_removed_func listener_removed, void *data, - int *out_listener_id) -{ - struct bt_graph_listener_port_removed listener = { - .base = { - .removed = listener_removed, - .data = data, - }, - .func = (port_removed_func_t) func, - }; - int listener_id; - - BT_ASSERT_PRE_NON_NULL(graph, "Graph"); - BT_ASSERT_PRE_NON_NULL(func, "Listener"); - BT_ASSERT_PRE_NON_NULL(func, "\"Listener removed\" listener"); - BT_ASSERT_PRE(!graph->in_remove_listener, - "Graph currently executing a \"listener removed\" listener: " - "%!+g", graph); - g_array_append_val(graph->listeners.filter_input_port_removed, listener); - listener_id = graph->listeners.filter_input_port_removed->len - 1; - BT_LIB_LOGV("Added \"filter component input port removed\" listener to graph: " - "%![graph-]+g, listener-addr=%p, id=%d", graph, listener, - listener_id); - - if (listener_id) { - *out_listener_id = listener_id; - } - - return BT_GRAPH_STATUS_OK; -} - -enum bt_graph_status -bt_graph_add_sink_component_input_port_removed_listener( - struct bt_graph *graph, - bt_graph_sink_component_input_port_removed_listener_func func, - bt_graph_listener_removed_func listener_removed, void *data, - int *out_listener_id) -{ - struct bt_graph_listener_port_removed listener = { - .base = { - .removed = listener_removed, - .data = data, - }, - .func = (port_removed_func_t) func, - }; - int listener_id; - - BT_ASSERT_PRE_NON_NULL(graph, "Graph"); - BT_ASSERT_PRE_NON_NULL(func, "Listener"); - BT_ASSERT_PRE_NON_NULL(func, "\"Listener removed\" listener"); - BT_ASSERT_PRE(!graph->in_remove_listener, - "Graph currently executing a \"listener removed\" listener: " - "%!+g", graph); - g_array_append_val(graph->listeners.sink_input_port_removed, listener); - listener_id = graph->listeners.sink_input_port_removed->len - 1; - BT_LIB_LOGV("Added \"sink component input port removed\" listener to graph: " - "%![graph-]+g, listener-addr=%p, id=%d", graph, listener, - listener_id); - - if (listener_id) { - *out_listener_id = listener_id; - } - - return BT_GRAPH_STATUS_OK; -} - enum bt_graph_status bt_graph_add_source_filter_component_ports_connected_listener( struct bt_graph *graph, @@ -1201,9 +986,9 @@ bt_graph_add_source_sink_component_ports_connected_listener( } enum bt_graph_status -bt_graph_add_filter_sink_component_ports_connected_listener( +bt_graph_add_filter_filter_component_ports_connected_listener( struct bt_graph *graph, - bt_graph_filter_sink_component_ports_connected_listener_func func, + bt_graph_filter_filter_component_ports_connected_listener_func func, bt_graph_listener_removed_func listener_removed, void *data, int *out_listener_id) { @@ -1222,10 +1007,10 @@ bt_graph_add_filter_sink_component_ports_connected_listener( BT_ASSERT_PRE(!graph->in_remove_listener, "Graph currently executing a \"listener removed\" listener: " "%!+g", graph); - g_array_append_val(graph->listeners.filter_sink_ports_connected, + g_array_append_val(graph->listeners.filter_filter_ports_connected, listener); - listener_id = graph->listeners.filter_sink_ports_connected->len - 1; - BT_LIB_LOGV("Added \"filter to sink component ports connected\" listener to graph: " + listener_id = graph->listeners.filter_filter_ports_connected->len - 1; + BT_LIB_LOGV("Added \"filter to filter component ports connected\" listener to graph: " "%![graph-]+g, listener-addr=%p, id=%d", graph, listener, listener_id); @@ -1237,90 +1022,18 @@ bt_graph_add_filter_sink_component_ports_connected_listener( } enum bt_graph_status -bt_graph_add_source_filter_component_ports_disconnected_listener( - struct bt_graph *graph, - bt_graph_source_filter_component_ports_disconnected_listener_func func, - bt_graph_listener_removed_func listener_removed, void *data, - int *out_listener_id) -{ - struct bt_graph_listener_ports_disconnected listener = { - .base = { - .removed = listener_removed, - .data = data, - }, - .func = (ports_disconnected_func_t) func, - }; - int listener_id; - - BT_ASSERT_PRE_NON_NULL(graph, "Graph"); - BT_ASSERT_PRE_NON_NULL(func, "Listener"); - BT_ASSERT_PRE_NON_NULL(func, "\"Listener removed\" listener"); - BT_ASSERT_PRE(!graph->in_remove_listener, - "Graph currently executing a \"listener removed\" listener: " - "%!+g", graph); - g_array_append_val(graph->listeners.source_filter_ports_disconnected, - listener); - listener_id = graph->listeners.source_filter_ports_disconnected->len - 1; - BT_LIB_LOGV("Added \"source to filter component ports disconnected\" listener to graph: " - "%![graph-]+g, listener-addr=%p, id=%d", graph, listener, - listener_id); - - if (listener_id) { - *out_listener_id = listener_id; - } - - return BT_GRAPH_STATUS_OK; -} - -enum bt_graph_status -bt_graph_add_source_sink_component_ports_disconnected_listener( - struct bt_graph *graph, - bt_graph_source_sink_component_ports_disconnected_listener_func func, - bt_graph_listener_removed_func listener_removed, void *data, - int *out_listener_id) -{ - struct bt_graph_listener_ports_disconnected listener = { - .base = { - .removed = listener_removed, - .data = data, - }, - .func = (ports_disconnected_func_t) func, - }; - int listener_id; - - BT_ASSERT_PRE_NON_NULL(graph, "Graph"); - BT_ASSERT_PRE_NON_NULL(func, "Listener"); - BT_ASSERT_PRE_NON_NULL(func, "\"Listener removed\" listener"); - BT_ASSERT_PRE(!graph->in_remove_listener, - "Graph currently executing a \"listener removed\" listener: " - "%!+g", graph); - g_array_append_val(graph->listeners.source_sink_ports_disconnected, - listener); - listener_id = graph->listeners.source_sink_ports_disconnected->len - 1; - BT_LIB_LOGV("Added \"source to sink component ports disconnected\" listener to graph: " - "%![graph-]+g, listener-addr=%p, id=%d", graph, listener, - listener_id); - - if (listener_id) { - *out_listener_id = listener_id; - } - - return BT_GRAPH_STATUS_OK; -} - -enum bt_graph_status -bt_graph_add_filter_sink_component_ports_disconnected_listener( +bt_graph_add_filter_sink_component_ports_connected_listener( struct bt_graph *graph, - bt_graph_filter_sink_component_ports_disconnected_listener_func func, + bt_graph_filter_sink_component_ports_connected_listener_func func, bt_graph_listener_removed_func listener_removed, void *data, int *out_listener_id) { - struct bt_graph_listener_ports_disconnected listener = { + struct bt_graph_listener_ports_connected listener = { .base = { .removed = listener_removed, .data = data, }, - .func = (ports_disconnected_func_t) func, + .func = (ports_connected_func_t) func, }; int listener_id; @@ -1330,10 +1043,10 @@ bt_graph_add_filter_sink_component_ports_disconnected_listener( BT_ASSERT_PRE(!graph->in_remove_listener, "Graph currently executing a \"listener removed\" listener: " "%!+g", graph); - g_array_append_val(graph->listeners.filter_sink_ports_disconnected, + g_array_append_val(graph->listeners.filter_sink_ports_connected, listener); - listener_id = graph->listeners.filter_sink_ports_disconnected->len - 1; - BT_LIB_LOGV("Added \"filter to sink component ports disconnected\" listener to graph: " + listener_id = graph->listeners.filter_sink_ports_connected->len - 1; + BT_LIB_LOGV("Added \"filter to sink component ports connected\" listener to graph: " "%![graph-]+g, listener-addr=%p, id=%d", graph, listener, listener_id); @@ -1345,11 +1058,13 @@ bt_graph_add_filter_sink_component_ports_disconnected_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); @@ -1407,85 +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); - } -} - -BT_HIDDEN -void bt_graph_notify_port_removed(struct bt_graph *graph, - struct bt_component *comp, struct bt_port *port) -{ - uint64_t i; - GArray *listeners; - - BT_ASSERT(graph); - BT_ASSERT(port); - BT_LIB_LOGV("Notifying graph listeners that a port was removed: " - "%![graph-]+g, %![comp-]+c, %![port-]+p", graph, comp, port); - - switch (comp->class->type) { - case BT_COMPONENT_CLASS_TYPE_SOURCE: - { - switch (port->type) { - case BT_PORT_TYPE_OUTPUT: - listeners = graph->listeners.source_output_port_removed; - break; - default: - abort(); - } - - break; - } - case BT_COMPONENT_CLASS_TYPE_FILTER: - { - switch (port->type) { - case BT_PORT_TYPE_INPUT: - listeners = graph->listeners.filter_input_port_removed; - break; - case BT_PORT_TYPE_OUTPUT: - listeners = graph->listeners.filter_output_port_removed; - break; - default: - abort(); - } - break; - } - case BT_COMPONENT_CLASS_TYPE_SINK: - { - switch (port->type) { - case BT_PORT_TYPE_INPUT: - listeners = graph->listeners.sink_input_port_removed; - break; - default: - abort(); + BT_ASSERT(listener->func); + status = listener->func(comp, port, listener->base.data); + if (status != BT_GRAPH_LISTENER_STATUS_OK) { + goto end; } - - break; - } - default: - abort(); } - for (i = 0; i < listeners->len; i++) { - struct bt_graph_listener_port_removed *listener = - &g_array_index(listeners, - struct bt_graph_listener_port_removed, i); - - BT_ASSERT(listener->func); - listener->func(comp, port, listener->base.data); - } +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); @@ -1519,6 +1177,10 @@ void bt_graph_notify_ports_connected(struct bt_graph *graph, case BT_COMPONENT_CLASS_TYPE_FILTER: { switch (downstream_comp->class->type) { + case BT_COMPONENT_CLASS_TYPE_FILTER: + listeners = + graph->listeners.filter_filter_ports_connected; + break; case BT_COMPONENT_CLASS_TYPE_SINK: listeners = graph->listeners.filter_sink_ports_connected; @@ -1539,80 +1201,18 @@ 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); - } -} - -BT_HIDDEN -void bt_graph_notify_ports_disconnected(struct bt_graph *graph, - struct bt_component *upstream_comp, - struct bt_component *downstream_comp, - struct bt_port *upstream_port, - struct bt_port *downstream_port) -{ - uint64_t i; - GArray *listeners; - - BT_ASSERT(graph); - BT_ASSERT(upstream_comp); - BT_ASSERT(downstream_comp); - BT_ASSERT(upstream_port); - BT_ASSERT(downstream_port); - BT_LIB_LOGV("Notifying graph listeners that ports were disconnected: " - "%![graph-]+g, %![up-port-]+p, %![down-port-]+p, " - "%![up-comp-]+c, %![down-comp-]+c", - graph, upstream_port, downstream_port, upstream_comp, - downstream_comp); - - switch (upstream_comp->class->type) { - case BT_COMPONENT_CLASS_TYPE_SOURCE: - { - switch (downstream_comp->class->type) { - case BT_COMPONENT_CLASS_TYPE_FILTER: - listeners = - graph->listeners.source_filter_ports_disconnected; - break; - case BT_COMPONENT_CLASS_TYPE_SINK: - listeners = - graph->listeners.source_sink_ports_disconnected; - break; - default: - abort(); - } - - break; - } - case BT_COMPONENT_CLASS_TYPE_FILTER: - { - switch (downstream_comp->class->type) { - case BT_COMPONENT_CLASS_TYPE_SINK: - listeners = - graph->listeners.filter_sink_ports_disconnected; - break; - default: - abort(); + if (status != BT_GRAPH_LISTENER_STATUS_OK) { + goto end; } - - break; - } - default: - abort(); } - for (i = 0; i < listeners->len; i++) { - struct bt_graph_listener_ports_disconnected *listener = - &g_array_index(listeners, - struct bt_graph_listener_ports_disconnected, i); - - BT_ASSERT(listener->func); - listener->func(upstream_comp, downstream_comp, - upstream_port, downstream_port, listener->base.data); - } +end: + return status; } -enum bt_graph_status bt_graph_cancel( - struct bt_graph *graph) +enum bt_graph_status bt_graph_cancel(struct bt_graph *graph) { BT_ASSERT_PRE_NON_NULL(graph, "Graph"); @@ -1680,6 +1280,9 @@ enum bt_graph_status add_component_with_init_method_data( BT_ASSERT_PRE_NON_NULL(graph, "Graph"); BT_ASSERT_PRE_NON_NULL(name, "Name"); BT_ASSERT_PRE(!graph->canceled, "Graph is canceled: %!+g", graph); + BT_ASSERT_PRE( + graph->config_state == BT_GRAPH_CONFIGURATION_STATE_CONFIGURING, + "Graph is not in the \"configuring\" state: %!+g", graph); BT_ASSERT_PRE(!component_name_exists(graph, name), "Duplicate component name: %!+g, name=\"%s\"", graph, name); BT_ASSERT_PRE(!params || bt_value_is_map(params), @@ -1717,6 +1320,7 @@ enum bt_graph_status add_component_with_init_method_data( */ g_ptr_array_add(graph->components, component); bt_component_set_graph(component, graph); + bt_value_freeze(params); if (init_method) { BT_LOGD_STR("Calling user's initialization method."); @@ -1765,6 +1369,10 @@ enum bt_graph_status add_component_with_init_method_data( } end: + if (graph_status != BT_GRAPH_STATUS_OK) { + bt_graph_make_faulty(graph); + } + bt_object_put_ref(component); bt_object_put_ref(new_params); (void) init_can_consume;