the_graph = ctx->graph;
ret = bt_graph_add_port_added_listener(ctx->graph,
- graph_port_added_listener, ctx);
+ graph_port_added_listener, NULL, ctx);
if (ret < 0) {
BT_LOGE_STR("Cannot add \"port added\" listener to graph.");
goto error;
}
ret = bt_graph_add_port_removed_listener(ctx->graph,
- graph_port_removed_listener, ctx);
+ graph_port_removed_listener, NULL, ctx);
if (ret < 0) {
BT_LOGE_STR("Cannot add \"port removed\" listener to graph.");
goto error;
}
ret = bt_graph_add_ports_connected_listener(ctx->graph,
- graph_ports_connected_listener, ctx);
+ graph_ports_connected_listener, NULL, ctx);
if (ret < 0) {
BT_LOGE_STR("Cannot add \"ports connected\" listener to graph.");
goto error;
}
ret = bt_graph_add_ports_disconnected_listener(ctx->graph,
- graph_ports_disconnected_listener, ctx);
+ graph_ports_disconnected_listener, NULL, ctx);
if (ret < 0) {
BT_LOGE_STR("Cannot add \"ports disconnected\" listener to graph.");
goto error;
struct bt_component *downstream_component,
struct bt_port *upstream_port, struct bt_port *downstream_port,
void *data);
+typedef void (* bt_graph_listener_removed)(void *data);
extern struct bt_graph *bt_graph_create(void);
extern enum bt_graph_status bt_graph_consume(struct bt_graph *graph);
extern int bt_graph_add_port_added_listener(struct bt_graph *graph,
- bt_graph_port_added_listener listener, void *data);
+ bt_graph_port_added_listener listener,
+ bt_graph_listener_removed listener_removed, void *data);
extern int bt_graph_add_port_removed_listener(struct bt_graph *graph,
- bt_graph_port_removed_listener listener, void *data);
+ bt_graph_port_removed_listener listener,
+ bt_graph_listener_removed listener_removed, void *data);
extern int bt_graph_add_ports_connected_listener(struct bt_graph *graph,
- bt_graph_ports_connected_listener listener, void *data);
+ bt_graph_ports_connected_listener listener,
+ bt_graph_listener_removed listener_removed, void *data);
extern int bt_graph_add_ports_disconnected_listener(struct bt_graph *graph,
- bt_graph_ports_disconnected_listener listener, void *data);
+ bt_graph_ports_disconnected_listener listener,
+ bt_graph_listener_removed listener_removed, void *data);
extern enum bt_graph_status bt_graph_cancel(struct bt_graph *graph);
extern bt_bool bt_graph_is_canceled(struct bt_graph *graph);
struct bt_graph_listener {
void *func;
+ bt_graph_listener_removed removed;
void *data;
};
+static
+int init_listeners_array(GArray **listeners)
+{
+ int ret = 0;
+
+ assert(listeners);
+ *listeners = g_array_new(FALSE, TRUE, sizeof(struct bt_graph_listener));
+ if (!*listeners) {
+ BT_LOGE_STR("Failed to allocate one GArray.");
+ ret = -1;
+ goto end;
+ }
+
+end:
+ return ret;
+}
+
+static
+void call_remove_listeners(GArray *listeners)
+{
+ size_t i;
+
+ for (i = 0; i < listeners->len; i++) {
+ struct bt_graph_listener listener =
+ g_array_index(listeners, struct bt_graph_listener, i);
+
+ if (listener.removed) {
+ listener.removed(listener.data);
+ }
+ }
+}
+
static
void bt_graph_destroy(struct bt_object *obj)
{
*/
(void) bt_graph_cancel(graph);
+ /* Call all remove listeners */
+ call_remove_listeners(graph->listeners.port_added);
+ call_remove_listeners(graph->listeners.port_removed);
+ call_remove_listeners(graph->listeners.ports_connected);
+ call_remove_listeners(graph->listeners.ports_disconnected);
+
if (graph->connections) {
BT_LOGD_STR("Destroying connections.");
g_ptr_array_free(graph->connections, TRUE);
g_free(graph);
}
-static
-int init_listeners_array(GArray **listeners)
-{
- int ret = 0;
-
- assert(listeners);
- *listeners = g_array_new(FALSE, TRUE, sizeof(struct bt_graph_listener));
- if (!*listeners) {
- BT_LOGE_STR("Failed to allocate one GArray.");
- ret = -1;
- goto end;
- }
-
-end:
- return ret;
-}
-
struct bt_graph *bt_graph_create(void)
{
struct bt_graph *graph;
}
static
-int add_listener(GArray *listeners, void *func, void *data)
+int add_listener(GArray *listeners, void *func, void *removed, void *data)
{
struct bt_graph_listener listener = {
.func = func,
+ .removed = removed,
.data = data,
};
int bt_graph_add_port_added_listener(
struct bt_graph *graph,
- bt_graph_port_added_listener listener, void *data)
+ bt_graph_port_added_listener listener,
+ bt_graph_listener_removed listener_removed, void *data)
{
int ret;
goto end;
}
+ if (graph->in_remove_listener) {
+ BT_LOGW("Cannot call this function during the execution of a remove listener: "
+ "addr=%p", graph);
+ ret = -1;
+ goto end;
+ }
+
if (!listener) {
BT_LOGW_STR("Invalid parameter: listener is NULL.");
ret = -1;
goto end;
}
- ret = add_listener(graph->listeners.port_added, listener, data);
+ ret = add_listener(graph->listeners.port_added, listener,
+ listener_removed, data);
BT_LOGV("Added \"port added\" listener to graph: "
"graph-addr=%p, listener-addr=%p, pos=%d",
graph, listener, ret);
int bt_graph_add_port_removed_listener(
struct bt_graph *graph,
- bt_graph_port_removed_listener listener, void *data)
+ bt_graph_port_removed_listener listener,
+ bt_graph_listener_removed listener_removed, void *data)
{
int ret;
goto end;
}
+ if (graph->in_remove_listener) {
+ BT_LOGW("Cannot call this function during the execution of a remove listener: "
+ "addr=%p", graph);
+ ret = -1;
+ goto end;
+ }
+
if (!listener) {
BT_LOGW_STR("Invalid parameter: listener is NULL.");
ret = -1;
goto end;
}
- ret = add_listener(graph->listeners.port_removed, listener, data);
+ ret = add_listener(graph->listeners.port_removed, listener,
+ listener_removed, data);
BT_LOGV("Added \"port removed\" listener to graph: "
"graph-addr=%p, listener-addr=%p, pos=%d",
graph, listener, ret);
int bt_graph_add_ports_connected_listener(
struct bt_graph *graph,
- bt_graph_ports_connected_listener listener, void *data)
+ bt_graph_ports_connected_listener listener,
+ bt_graph_listener_removed listener_removed, void *data)
{
int ret;
goto end;
}
+ if (graph->in_remove_listener) {
+ BT_LOGW("Cannot call this function during the execution of a remove listener: "
+ "addr=%p", graph);
+ ret = -1;
+ goto end;
+ }
+
if (!listener) {
BT_LOGW_STR("Invalid parameter: listener is NULL.");
ret = -1;
goto end;
}
- ret = add_listener(graph->listeners.ports_connected, listener, data);
+ ret = add_listener(graph->listeners.ports_connected, listener,
+ listener_removed, data);
BT_LOGV("Added \"port connected\" listener to graph: "
"graph-addr=%p, listener-addr=%p, pos=%d",
graph, listener, ret);
int bt_graph_add_ports_disconnected_listener(
struct bt_graph *graph,
- bt_graph_ports_disconnected_listener listener, void *data)
+ bt_graph_ports_disconnected_listener listener,
+ bt_graph_listener_removed listener_removed, void *data)
{
int ret;
goto end;
}
+ if (graph->in_remove_listener) {
+ BT_LOGW("Cannot call this function during the execution of a remove listener: "
+ "addr=%p", graph);
+ ret = -1;
+ goto end;
+ }
+
if (!listener) {
BT_LOGW_STR("Invalid parameter: listener is NULL.");
ret = -1;
goto end;
}
- ret = add_listener(graph->listeners.ports_disconnected, listener, data);
+ ret = add_listener(graph->listeners.ports_disconnected, listener,
+ listener_removed, data);
BT_LOGV("Added \"port disconnected\" listener to graph: "
"graph-addr=%p, listener-addr=%p, pos=%d",
graph, listener, ret);