X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=lib%2Fgraph%2Fgraph.c;h=f7b02a10bece15a7914d8612e362f058328bcc6e;hb=68b66a256a54d32992dfefeaad11eea88b7df234;hp=4f888b7a991ba6f6479df42340a9b2eb23cac697;hpb=c6bd8523ba4a37b61a1591c03e23614112b155ba;p=babeltrace.git diff --git a/lib/graph/graph.c b/lib/graph/graph.c index 4f888b7a..f7b02a10 100644 --- a/lib/graph/graph.c +++ b/lib/graph/graph.c @@ -1,6 +1,6 @@ /* + * Copyright 2017-2018 Philippe Proulx * Copyright 2017 Jérémie Galarneau - * Copyright 2017 Philippe Proulx * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -22,42 +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 #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 *); @@ -71,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)); \ @@ -98,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); \ @@ -119,21 +107,21 @@ 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 - * notification iterators. - * 3. A notification 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. - * 5. The notification iterator's finalization function puts its + * 5. The message iterator's finalization function puts its * component reference (reference count goes from 1 to 0). * 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 @@ -144,7 +132,7 @@ void destroy_graph(struct bt_object *obj) /* * Cancel the graph to disallow some operations, like creating - * notification iterators and adding ports to components. + * message iterators and adding ports to components. */ (void) bt_graph_cancel((void *) graph); @@ -157,30 +145,18 @@ 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->notifications) { - g_ptr_array_free(graph->notifications, TRUE); - graph->notifications = NULL; + if (graph->messages) { + g_ptr_array_free(graph->messages, TRUE); + graph->messages = NULL; } if (graph->connections) { @@ -220,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); @@ -258,55 +220,37 @@ 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_notif_pool); - bt_object_pool_finalize(&graph->packet_begin_notif_pool); - bt_object_pool_finalize(&graph->packet_end_notif_pool); + 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); g_free(graph); } static -void destroy_notification_event(struct bt_notification *notif, +void destroy_message_event(struct bt_message *msg, struct bt_graph *graph) { - bt_notification_event_destroy(notif); + bt_message_event_destroy(msg); } static -void destroy_notification_packet_begin(struct bt_notification *notif, +void destroy_message_packet_begin(struct bt_message *msg, struct bt_graph *graph) { - bt_notification_packet_beginning_destroy(notif); + bt_message_packet_destroy(msg); } static -void destroy_notification_packet_end(struct bt_notification *notif, +void destroy_message_packet_end(struct bt_message *msg, struct bt_graph *graph) { - bt_notification_packet_end_destroy(notif); + bt_message_packet_destroy(msg); } static -void notify_notification_graph_is_destroyed(struct bt_notification *notif) +void notify_message_graph_is_destroyed(struct bt_message *msg) { - bt_notification_unlink_graph(notif); + bt_message_unlink_graph(msg); } struct bt_graph *bt_graph_create(void) @@ -373,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); @@ -422,69 +334,53 @@ struct bt_graph *bt_graph_create(void) } INIT_LISTENERS_ARRAY(struct bt_graph_listener_ports_connected, - graph->listeners.filter_sink_ports_connected); + graph->listeners.filter_filter_ports_connected); - if (!graph->listeners.filter_sink_ports_connected) { + if (!graph->listeners.filter_filter_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; - } - - INIT_LISTENERS_ARRAY(struct bt_graph_listener_ports_disconnected, - graph->listeners.source_sink_ports_disconnected); - - if (!graph->listeners.source_sink_ports_disconnected) { - 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; } - ret = bt_object_pool_initialize(&graph->event_notif_pool, - (bt_object_pool_new_object_func) bt_notification_event_new, - (bt_object_pool_destroy_object_func) destroy_notification_event, + ret = bt_object_pool_initialize(&graph->event_msg_pool, + (bt_object_pool_new_object_func) bt_message_event_new, + (bt_object_pool_destroy_object_func) destroy_message_event, graph); if (ret) { - BT_LOGE("Failed to initialize event notification pool: ret=%d", + BT_LOGE("Failed to initialize event message pool: ret=%d", ret); goto error; } - ret = bt_object_pool_initialize(&graph->packet_begin_notif_pool, - (bt_object_pool_new_object_func) bt_notification_packet_beginning_new, - (bt_object_pool_destroy_object_func) destroy_notification_packet_begin, + ret = bt_object_pool_initialize(&graph->packet_begin_msg_pool, + (bt_object_pool_new_object_func) bt_message_packet_beginning_new, + (bt_object_pool_destroy_object_func) destroy_message_packet_begin, graph); if (ret) { - BT_LOGE("Failed to initialize packet beginning notification pool: ret=%d", + BT_LOGE("Failed to initialize packet beginning message pool: ret=%d", ret); goto error; } - ret = bt_object_pool_initialize(&graph->packet_end_notif_pool, - (bt_object_pool_new_object_func) bt_notification_packet_end_new, - (bt_object_pool_destroy_object_func) destroy_notification_packet_end, + ret = bt_object_pool_initialize(&graph->packet_end_msg_pool, + (bt_object_pool_new_object_func) bt_message_packet_end_new, + (bt_object_pool_destroy_object_func) destroy_message_packet_end, graph); if (ret) { - BT_LOGE("Failed to initialize packet end notification pool: ret=%d", + BT_LOGE("Failed to initialize packet end message pool: ret=%d", ret); goto error; } - graph->notifications = g_ptr_array_new_with_free_func( - (GDestroyNotify) notify_notification_graph_is_destroyed); + graph->messages = g_ptr_array_new_with_free_func( + (GDestroyNotify) notify_message_graph_is_destroyed); BT_LIB_LOGD("Created graph object: %!+g", graph); end: @@ -502,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; @@ -514,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), @@ -633,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, " @@ -648,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); @@ -777,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; @@ -786,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 { @@ -833,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); @@ -845,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; } @@ -989,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, @@ -1202,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) { @@ -1223,46 +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, - listener); - 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); - - if (listener_id) { - *out_listener_id = listener_id; - } - - return BT_GRAPH_STATUS_OK; -} - -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, + g_array_append_val(graph->listeners.filter_filter_ports_connected, listener); - listener_id = graph->listeners.source_filter_ports_disconnected->len - 1; - BT_LIB_LOGV("Added \"source to filter component ports disconnected\" 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); @@ -1274,54 +1022,18 @@ bt_graph_add_source_filter_component_ports_disconnected_listener( } 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; @@ -1331,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); @@ -1346,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); @@ -1408,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); @@ -1520,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; @@ -1540,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"); @@ -1681,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), @@ -1718,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."); @@ -1766,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; @@ -1921,19 +1528,29 @@ end: } BT_HIDDEN -void bt_graph_add_notification(struct bt_graph *graph, - struct bt_notification *notif) +void bt_graph_add_message(struct bt_graph *graph, + struct bt_message *msg) { BT_ASSERT(graph); - BT_ASSERT(notif); + BT_ASSERT(msg); /* * It's okay not to take a reference because, when a - * notification's reference count drops to 0, either: + * message's reference count drops to 0, either: * * * It is recycled back to one of this graph's pool. * * It is destroyed because it doesn't have any link to any * graph, which means the original graph is already destroyed. */ - g_ptr_array_add(graph->notifications, notif); + g_ptr_array_add(graph->messages, msg); +} + +void bt_graph_get_ref(const struct bt_graph *graph) +{ + bt_object_get_ref(graph); +} + +void bt_graph_put_ref(const struct bt_graph *graph) +{ + bt_object_put_ref(graph); }