diff options
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.patch | 72 |
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 + |