summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/pulsecore/sink-input.c26
-rw-r--r--src/pulsecore/source-output.c27
2 files changed, 53 insertions, 0 deletions
diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c
index 2ceed412d..4155b69a5 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 fa32a5666..a4c99af0e 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;