Clean up node status after sink_input unlink
authorManuel Bachmann <manuel.bachmann@iot.bzh>
Mon, 13 Jun 2016 08:11:28 +0000 (10:11 +0200)
committerYannick Gicquel <yannick.gicquel@iot.bzh>
Tue, 11 Oct 2016 15:09:07 +0000 (17:09 +0200)
We now unload all modules associated with a node when
it disappears.

Change-Id: I6d2055d546c9cc1b1967f85c973eafcc216bc91f
Signed-off-by: Manuel Bachmann <manuel.bachmann@iot.bzh>
discover.c
router.c
router.h
switch.c
tracker.c

index eea6986..93a5d8b 100644 (file)
@@ -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);
 }
index 855f9f8..2478ab2 100644 (file)
--- 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);
+       }
+}
index ffb9361..93b29d8 100644 (file)
--- 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
index 5b77180..05386a0 100644 (file)
--- 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;
 }
index cb6369a..95c5f0a 100644 (file)
--- 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;
 }