From 6fc3e02df9de8347eb76fdfd26ed781686d37b6c Mon Sep 17 00:00:00 2001 From: Manuel Bachmann Date: Mon, 13 Jun 2016 10:11:28 +0200 Subject: [PATCH] Clean up node status after sink_input unlink We now unload all modules associated with a node when it disappears. Change-Id: I6d2055d546c9cc1b1967f85c973eafcc216bc91f Signed-off-by: Manuel Bachmann --- discover.c | 24 ++++++++++++++++++++++-- router.c | 25 +++++++++++++++++++++++++ router.h | 4 ++++ switch.c | 44 +++++++++++++++++--------------------------- tracker.c | 6 ++++++ 5 files changed, 74 insertions(+), 29 deletions(-) diff --git a/discover.c b/discover.c index eea6986..93a5d8b 100644 --- a/discover.c +++ b/discover.c @@ -757,6 +757,26 @@ void pa_discover_add_sink_input (struct userdata *u, pa_sink_input *sinp) node = agl_node_get_from_client (u, sinp->client); if (!node) return; - /* start the default routing */ - implement_default_route (u, node, NULL, pa_utils_new_stamp ()); + /* start routing */ + agl_router_register_node (u, node); +} + +void pa_discover_remove_sink_input (struct userdata *u, pa_sink_input *sinp) +{ + pa_core *core; + agl_node *node; + + pa_assert (u); + pa_assert (sinp); + pa_assert_se (core = u->core); + + if (!sinp->client) + return; + + /* is there an existing matching node ? */ + node = agl_node_get_from_client (u, sinp->client); + if (!node) return; + + /* stop routing */ + agl_router_unregister_node (u, node); } diff --git a/router.c b/router.c index 855f9f8..2478ab2 100644 --- a/router.c +++ b/router.c @@ -84,6 +84,22 @@ void pa_router_done (struct userdata *u) } } +void agl_router_register_node (struct userdata *u, agl_node *node) +{ + pa_assert (u); + pa_assert (node); + + implement_default_route (u, node, NULL, pa_utils_new_stamp ()); +} + +void agl_router_unregister_node (struct userdata *u, agl_node *node) +{ + pa_assert (u); + pa_assert (node); + + remove_routes (u, node, NULL, pa_utils_new_stamp ()); +} + agl_node *agl_router_make_prerouting (struct userdata *u, agl_node *data) { pa_router *router; @@ -196,3 +212,12 @@ agl_node *find_default_route (struct userdata *u, agl_node *start, uint32_t stam return NULL; } + +void remove_routes (struct userdata *u, agl_node *start, agl_node *end, uint32_t stamp) +{ + if (start->direction == agl_input) { + agl_switch_teardown_link (u, start, end); + } else { + agl_switch_teardown_link (u, end, start); + } +} diff --git a/router.h b/router.h index ffb9361..93b29d8 100644 --- a/router.h +++ b/router.h @@ -70,10 +70,14 @@ struct agl_connection { pa_router *pa_router_init (struct userdata *); void pa_router_done (struct userdata *); + +void agl_router_register_node (struct userdata *, agl_node *); +void agl_router_unregister_node (struct userdata *, agl_node *); agl_node *agl_router_make_prerouting (struct userdata *, agl_node *); void agl_router_make_routing (struct userdata *); void implement_default_route (struct userdata *, agl_node *, agl_node *, uint32_t); agl_node *find_default_route (struct userdata *, agl_node *, uint32_t); +void remove_routes (struct userdata *, agl_node *, agl_node*, uint32_t); #endif diff --git a/switch.c b/switch.c index 5b77180..05386a0 100644 --- a/switch.c +++ b/switch.c @@ -135,7 +135,7 @@ bool agl_switch_setup_link (struct userdata *u, agl_node *from, agl_node *to, bo /* ONLY "FROM" IS DEFINED */ else { - /* only works with a device, use default input prerouting - TODO */ + /* only works with a stream, use default input prerouting */ if (from->implement == agl_device) { pa_log_debug ("default routing for a device input is not supported yet"); return false; @@ -165,38 +165,28 @@ bool agl_switch_teardown_link (struct userdata *u, agl_node *from, agl_node *to) pa_assert (u); pa_assert_se (core = u->core); - pa_assert (from || from->direction == agl_input); - pa_assert (to || to->direction == agl_output); - switch (from->implement) { - case agl_stream: - switch (to->implement) { - /* STREAM TO STREAM : NOT IMPLEMENTED */ - case agl_stream: - pa_log_debug ("routing to streams is not implemented yet"); - break; - /* STREAM TO DEVICE : NOT OK */ - case agl_device: - //if (!teardown_explicit_stream2dev_link (u, from, to)) - // return false; - break; - default: - pa_log ("can't teardown link: invalid sink node"); - return false; - } - break; + pa_assert (from || to); - case agl_device: - /* DEVICE TO STREAM OR DEVICE TO DEVICE : NOT HANDLED */ - pa_log_debug ("input device routing is not implemented yet"); - break; + /* "TO" IS DEFINED */ + if (to) { - default: - pa_log ("can't teardown link: invalid source node"); + } + /* ONLY "FROM" IS DEFINED */ + else { + /* only works with a stream */ + if (from->implement == agl_device) { + pa_log_debug ("default routing for a device input is not supported"); return false; + } + /* (the rest supposes "from->implement == agl_stream") */ + if (from->loopnode) + pa_loopnode_destroy (u, from->loopnode); + if (from->nullsink) + pa_utils_destroy_null_sink (u, from->nullsink); } - pa_log_debug("link %s => %s is torn down", from->amname, to->amname); + //pa_log_debug("link %s => %s is torn down", from->amname, to->amname); return true; } diff --git a/tracker.c b/tracker.c index cb6369a..95c5f0a 100644 --- a/tracker.c +++ b/tracker.c @@ -346,6 +346,12 @@ static pa_hook_result_t sink_input_unlink (void *hook_data, void *call_data, void *slot_data) { + /* called by each client when stopping sound */ + pa_sink_input *sinp = (pa_sink_input *)call_data; + struct userdata *u = (struct userdata *)slot_data; + + pa_discover_remove_sink_input (u, sinp); + return PA_HOOK_OK; } -- 2.16.6