summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'media-sound/pulseaudio-daemon/files/pulseaudio-16.0-fix-combine-sink-underrun-crash.patch')
-rw-r--r--media-sound/pulseaudio-daemon/files/pulseaudio-16.0-fix-combine-sink-underrun-crash.patch72
1 files changed, 72 insertions, 0 deletions
diff --git a/media-sound/pulseaudio-daemon/files/pulseaudio-16.0-fix-combine-sink-underrun-crash.patch b/media-sound/pulseaudio-daemon/files/pulseaudio-16.0-fix-combine-sink-underrun-crash.patch
new file mode 100644
index 000000000000..d66d75afdfda
--- /dev/null
+++ b/media-sound/pulseaudio-daemon/files/pulseaudio-16.0-fix-combine-sink-underrun-crash.patch
@@ -0,0 +1,72 @@
+https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/commit/ee8bfb49adddd271d8a8cafa796c6f9fa84de48a
+
+From ee8bfb49adddd271d8a8cafa796c6f9fa84de48a Mon Sep 17 00:00:00 2001
+From: Georg Chini <georg@chini.tk>
+Date: Fri, 17 Jun 2022 13:11:11 +0200
+Subject: [PATCH] combine-sink: Fix threading issue during underrun
+
+A recent commit added i->origin sink for the sink inputs of the combine sinks.
+Therefore pa_sink_process_input_underruns() treated the combine sink like
+filter sinks. pa_sink_process_input_underruns() calls itself with the
+origin sink, which is only correct for filter sinks because they run in the
+thread context of the origin sink. The combine sink however has its own
+thread context, so pa_sink_process_input_underruns() was executed in the
+wrong context.
+This patch fixes the issue by skipping the section for module-combine-sink.
+
+Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/722>
+---
+ src/pulsecore/sink.c | 37 +++++++++++++++++++++++--------------
+ 1 file changed, 23 insertions(+), 14 deletions(-)
+
+diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c
+index 3108ae765..0f0dc56fc 100644
+--- a/src/pulsecore/sink.c
++++ b/src/pulsecore/sink.c
+@@ -1016,20 +1016,29 @@ size_t pa_sink_process_input_underruns(pa_sink *s, size_t left_to_play) {
+ if (i->origin_sink) {
+ size_t filter_result, left_to_play_origin;
+
+- /* The recursive call works in the origin sink domain ... */
+- left_to_play_origin = pa_convert_size(left_to_play, &i->sink->sample_spec, &i->origin_sink->sample_spec);
+-
+- /* .. and returns the time to sleep before waking up. We need the
+- * underrun duration for comparisons, so we undo the subtraction on
+- * the return value... */
+- filter_result = left_to_play_origin - pa_sink_process_input_underruns(i->origin_sink, left_to_play_origin);
+-
+- /* ... and convert it back to the master sink domain */
+- filter_result = pa_convert_size(filter_result, &i->origin_sink->sample_spec, &i->sink->sample_spec);
+-
+- /* Remember the longest underrun so far */
+- if (filter_result > result)
+- result = filter_result;
++ /* The combine sink sets i->origin sink but has a different threading model
++ * than the filter sinks. Therefore the recursion below may not be executed
++ * because pa_sink_process_input_underruns() was not called in the thread
++ * context of the origin sink.
++ * FIXME: It is unclear if some other kind of recursion would be necessary
++ * for the combine sink. */
++ if (!i->module || !pa_safe_streq(i->module->name, "module-combine-sink")) {
++
++ /* The recursive call works in the origin sink domain ... */
++ left_to_play_origin = pa_convert_size(left_to_play, &i->sink->sample_spec, &i->origin_sink->sample_spec);
++
++ /* .. and returns the time to sleep before waking up. We need the
++ * underrun duration for comparisons, so we undo the subtraction on
++ * the return value... */
++ filter_result = left_to_play_origin - pa_sink_process_input_underruns(i->origin_sink, left_to_play_origin);
++
++ /* ... and convert it back to the master sink domain */
++ filter_result = pa_convert_size(filter_result, &i->origin_sink->sample_spec, &i->sink->sample_spec);
++
++ /* Remember the longest underrun so far */
++ if (filter_result > result)
++ result = filter_result;
++ }
+ }
+
+ if (uf == 0) {
+--
+GitLab
+