From: Philippe Proulx Date: Wed, 12 Dec 2018 23:43:31 +0000 (-0500) Subject: Fix: graph API: add listeners to support filter-to-filter connection X-Git-Tag: v2.0.0-pre5~207 X-Git-Url: http://git.efficios.com/?p=babeltrace.git;a=commitdiff_plain;h=ee976410f24a0c1448d66e2b93e0b8fed6b86779 Fix: graph API: add listeners to support filter-to-filter connection Listeners existed to be notified when a source is connected to a filter or to a sink, or when a filter is connected to a sink, but not when a filter is connected to another filter. Reported-by: Francis Deslauriers Signed-off-by: Philippe Proulx --- diff --git a/include/babeltrace/graph/graph-internal.h b/include/babeltrace/graph/graph-internal.h index 09927fcf..7c1ac085 100644 --- a/include/babeltrace/graph/graph-internal.h +++ b/include/babeltrace/graph/graph-internal.h @@ -84,9 +84,11 @@ struct bt_graph { GArray *sink_input_port_removed; GArray *source_filter_ports_connected; GArray *source_sink_ports_connected; + GArray *filter_filter_ports_connected; GArray *filter_sink_ports_connected; GArray *source_filter_ports_disconnected; GArray *source_sink_ports_disconnected; + GArray *filter_filter_ports_disconnected; GArray *filter_sink_ports_disconnected; } listeners; diff --git a/include/babeltrace/graph/graph.h b/include/babeltrace/graph/graph.h index d3a9a875..33b109ec 100644 --- a/include/babeltrace/graph/graph.h +++ b/include/babeltrace/graph/graph.h @@ -84,6 +84,13 @@ typedef void (*bt_graph_source_sink_component_ports_connected_listener_func)( 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)( + 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)( const bt_component_filter *filter_component, const bt_component_sink *sink_component, @@ -104,6 +111,13 @@ typedef void (*bt_graph_source_sink_component_ports_disconnected_listener_func)( const bt_port_input *downstream_port, void *data); +typedef void (*bt_graph_filter_filter_component_ports_disconnected_listener_func)( + const bt_component_filter *filter_component_upstream, + const bt_component_filter *filter_component_downstream, + const bt_port_output *upstream_port, + const bt_port_input *downstream_port, + void *data); + typedef void (*bt_graph_filter_sink_component_ports_disconnected_listener_func)( const bt_component_filter *filter_component, const bt_component_sink *sink_component, @@ -223,6 +237,13 @@ bt_graph_add_source_filter_component_ports_connected_listener( bt_graph_listener_removed_func listener_removed, void *data, int *listener_id); +extern bt_graph_status +bt_graph_add_filter_filter_component_ports_connected_listener( + bt_graph *graph, + bt_graph_filter_filter_component_ports_connected_listener_func listener, + bt_graph_listener_removed_func listener_removed, void *data, + int *listener_id); + extern bt_graph_status bt_graph_add_source_sink_component_ports_connected_listener( bt_graph *graph, @@ -244,6 +265,13 @@ bt_graph_add_source_filter_component_ports_disconnected_listener( bt_graph_listener_removed_func listener_removed, void *data, int *listener_id); +extern bt_graph_status +bt_graph_add_filter_filter_component_ports_disconnected_listener( + bt_graph *graph, + bt_graph_filter_filter_component_ports_disconnected_listener_func listener, + bt_graph_listener_removed_func listener_removed, void *data, + int *listener_id); + extern bt_graph_status bt_graph_add_source_sink_component_ports_disconnected_listener( bt_graph *graph, diff --git a/lib/graph/graph.c b/lib/graph/graph.c index 3b48c561..19682e45 100644 --- a/lib/graph/graph.c +++ b/lib/graph/graph.c @@ -166,12 +166,16 @@ void destroy_graph(struct bt_object *obj) 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.filter_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, @@ -245,6 +249,12 @@ void destroy_graph(struct bt_object *obj) 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); @@ -269,6 +279,12 @@ void destroy_graph(struct bt_object *obj) graph->listeners.source_sink_ports_disconnected = NULL; } + if (graph->listeners.filter_filter_ports_disconnected) { + g_array_free(graph->listeners.filter_filter_ports_disconnected, + TRUE); + graph->listeners.filter_filter_ports_disconnected = NULL; + } + if (graph->listeners.filter_sink_ports_disconnected) { g_array_free(graph->listeners.filter_sink_ports_disconnected, TRUE); @@ -420,6 +436,14 @@ struct bt_graph *bt_graph_create(void) goto error; } + INIT_LISTENERS_ARRAY(struct bt_graph_listener_ports_connected, + graph->listeners.filter_filter_ports_connected); + + if (!graph->listeners.filter_filter_ports_connected) { + ret = -1; + goto error; + } + INIT_LISTENERS_ARRAY(struct bt_graph_listener_ports_connected, graph->listeners.filter_sink_ports_connected); @@ -444,6 +468,14 @@ struct bt_graph *bt_graph_create(void) goto error; } + INIT_LISTENERS_ARRAY(struct bt_graph_listener_ports_disconnected, + graph->listeners.filter_filter_ports_disconnected); + + if (!graph->listeners.filter_filter_ports_disconnected) { + ret = -1; + goto error; + } + INIT_LISTENERS_ARRAY(struct bt_graph_listener_ports_disconnected, graph->listeners.filter_sink_ports_disconnected); @@ -1200,6 +1232,42 @@ bt_graph_add_source_sink_component_ports_connected_listener( return BT_GRAPH_STATUS_OK; } +enum bt_graph_status +bt_graph_add_filter_filter_component_ports_connected_listener( + struct bt_graph *graph, + bt_graph_filter_filter_component_ports_connected_listener_func func, + bt_graph_listener_removed_func listener_removed, void *data, + int *out_listener_id) +{ + struct bt_graph_listener_ports_connected listener = { + .base = { + .removed = listener_removed, + .data = data, + }, + .func = (ports_connected_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_filter_ports_connected, + listener); + 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); + + if (listener_id) { + *out_listener_id = listener_id; + } + + return BT_GRAPH_STATUS_OK; +} + enum bt_graph_status bt_graph_add_filter_sink_component_ports_connected_listener( struct bt_graph *graph, @@ -1308,6 +1376,42 @@ bt_graph_add_source_sink_component_ports_disconnected_listener( return BT_GRAPH_STATUS_OK; } +enum bt_graph_status +bt_graph_add_filter_filter_component_ports_disconnected_listener( + struct bt_graph *graph, + bt_graph_filter_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.filter_filter_ports_disconnected, + listener); + listener_id = graph->listeners.filter_filter_ports_disconnected->len - 1; + BT_LIB_LOGV("Added \"filter 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_filter_sink_component_ports_disconnected_listener( struct bt_graph *graph, @@ -1519,6 +1623,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; @@ -1586,6 +1694,10 @@ void bt_graph_notify_ports_disconnected(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_disconnected; + break; case BT_COMPONENT_CLASS_TYPE_SINK: listeners = graph->listeners.filter_sink_ports_disconnected;