]> code.delx.au - pulseaudio/commitdiff
echo-cancel: Don't allow streams to attach while unloading
authorArun Raghavan <arun.raghavan@collabora.co.uk>
Mon, 29 Aug 2011 12:17:39 +0000 (17:47 +0530)
committerArun Raghavan <arun.raghavan@collabora.co.uk>
Mon, 29 Aug 2011 16:12:57 +0000 (21:42 +0530)
When unloading, some module may end up trin to move a sink-input or
source-output back onto our virtual sink/source, causing an infinite
loop of us moving the stream away and having it moved back.

We prevent this from happening by preventing any stream from being
attached during unload.

src/modules/echo-cancel/module-echo-cancel.c

index 706f2e7dd73a7af724e0a7608c97535dd76c00ce..acfbc04f6d2e6646725f1d3bc51086807e90805f 100644 (file)
@@ -156,6 +156,7 @@ struct userdata {
     pa_module *module;
 
     pa_bool_t autoloaded;
+    pa_bool_t dead;
     pa_bool_t save_aec;
 
     pa_echo_canceller *ec;
@@ -1162,6 +1163,8 @@ static void source_output_kill_cb(pa_source_output *o) {
     pa_assert_ctl_context();
     pa_assert_se(u = o->userdata);
 
+    u->dead = TRUE;
+
     /* The order here matters! We first kill the source output, followed
      * by the source. That means the source callbacks must be protected
      * against an unconnected source output! */
@@ -1186,6 +1189,8 @@ static void sink_input_kill_cb(pa_sink_input *i) {
     pa_sink_input_assert_ref(i);
     pa_assert_se(u = i->userdata);
 
+    u->dead = TRUE;
+
     /* The order here matters! We first kill the sink input, followed
      * by the sink. That means the sink callbacks must be protected
      * against an unconnected sink input! */
@@ -1211,6 +1216,9 @@ static pa_bool_t source_output_may_move_to_cb(pa_source_output *o, pa_source *de
     pa_assert_ctl_context();
     pa_assert_se(u = o->userdata);
 
+    if (u->dead)
+        return FALSE;
+
     return (u->source != dest) && (u->sink != dest->monitor_of);
 }
 
@@ -1221,6 +1229,9 @@ static pa_bool_t sink_input_may_move_to_cb(pa_sink_input *i, pa_sink *dest) {
     pa_sink_input_assert_ref(i);
     pa_assert_se(u = i->userdata);
 
+    if (u->dead)
+        return FALSE;
+
     return u->sink != dest;
 }
 
@@ -1362,6 +1373,7 @@ int pa__init(pa_module*m) {
     u->core = m->core;
     u->module = m;
     m->userdata = u;
+    u->dead = FALSE;
 
     u->ec = pa_xnew0(pa_echo_canceller, 1);
     if (!u->ec) {
@@ -1649,6 +1661,8 @@ void pa__done(pa_module*m) {
     if (!(u = m->userdata))
         return;
 
+    u->dead = TRUE;
+
     /* See comments in source_output_kill_cb() above regarding
      * destruction order! */