[pulseaudio-commits] src/pulsecore

Tanu Kaskinen tanuk at kemper.freedesktop.org
Thu May 18 20:34:49 UTC 2017


 src/pulsecore/sink-input.c    |   26 ++++++++++++++++++++++++++
 src/pulsecore/source-output.c |   27 +++++++++++++++++++++++++++
 2 files changed, 53 insertions(+)

New commits:
commit a7017b831e0d5b6f699fe05bc1b67a14c151ef12
Author: Tanu Kaskinen <tanuk at iki.fi>
Date:   Mon May 8 12:58:49 2017 +0300

    sink-input, source-output: don't allow moving streams that are connected to moving filter devices
    
    When a filter sink is moving, it's not connected to any master sink, and
    therefore it's not connected to any IO thread either. In this situation
    trying to move a stream that is connected to the filter sink is likely
    to result in crashing, because starting the move involves sending a
    message to the IO thread. Sometimes this works by accident (the
    asyncmsgq of the filter sink still points to the old master sink's
    asyncmsgq), but we really should never attempt it. This patch blocks all
    moves where the moving stream is connected to a filter sink that itself
    is in the middle of a move.
    
    BugLink: https://bugs.freedesktop.org/show_bug.cgi?id=100277

diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c
index 2ceed412..4155b69a 100644
--- a/src/pulsecore/sink-input.c
+++ b/src/pulsecore/sink-input.c
@@ -1627,6 +1627,22 @@ static bool find_filter_sink_input(pa_sink_input *target, pa_sink *s) {
     return false;
 }
 
+static bool is_filter_sink_moving(pa_sink_input *i) {
+    pa_sink *sink = i->sink;
+
+    if (!sink)
+        return false;
+
+    while (sink->input_to_master) {
+        sink = sink->input_to_master->sink;
+
+        if (!sink)
+            return true;
+    }
+
+    return false;
+}
+
 /* Called from main context */
 bool pa_sink_input_may_move_to(pa_sink_input *i, pa_sink *dest) {
     pa_sink_input_assert_ref(i);
@@ -1649,6 +1665,16 @@ bool pa_sink_input_may_move_to(pa_sink_input *i, pa_sink *dest) {
         return false;
     }
 
+    /* If this sink input is connected to a filter sink that itself is moving,
+     * then don't allow the move. Moving requires sending a message to the IO
+     * thread of the old sink, and if the old sink is a filter sink that is
+     * moving, there's no IO thread associated to the old sink. */
+    if (is_filter_sink_moving(i)) {
+        pa_log_debug("Can't move input from filter sink %s, because the filter sink itself is currently moving.",
+                     i->sink->name);
+        return false;
+    }
+
     if (pa_idxset_size(dest->inputs) >= PA_MAX_INPUTS_PER_SINK) {
         pa_log_warn("Failed to move sink input: too many inputs per sink.");
         return false;
diff --git a/src/pulsecore/source-output.c b/src/pulsecore/source-output.c
index fa32a566..a4c99af0 100644
--- a/src/pulsecore/source-output.c
+++ b/src/pulsecore/source-output.c
@@ -1265,6 +1265,22 @@ static bool find_filter_source_output(pa_source_output *target, pa_source *s) {
     return false;
 }
 
+static bool is_filter_source_moving(pa_source_output *o) {
+    pa_source *source = o->source;
+
+    if (!source)
+        return false;
+
+    while (source->output_from_master) {
+        source = source->output_from_master->source;
+
+        if (!source)
+            return true;
+    }
+
+    return false;
+}
+
 /* Called from main context */
 bool pa_source_output_may_move_to(pa_source_output *o, pa_source *dest) {
     pa_source_output_assert_ref(o);
@@ -1286,6 +1302,17 @@ bool pa_source_output_may_move_to(pa_source_output *o, pa_source *dest) {
         return false;
     }
 
+    /* If this source output is connected to a filter source that itself is
+     * moving, then don't allow the move. Moving requires sending a message to
+     * the IO thread of the old source, and if the old source is a filter
+     * source that is moving, there's no IO thread associated to the old
+     * source. */
+    if (is_filter_source_moving(o)) {
+        pa_log_debug("Can't move output from filter source %s, because the filter source itself is currently moving.",
+                     o->source->name);
+        return false;
+    }
+
     if (pa_idxset_size(dest->outputs) >= PA_MAX_OUTPUTS_PER_SOURCE) {
         pa_log_warn("Failed to move source output: too many outputs per source.");
         return false;



More information about the pulseaudio-commits mailing list