[pulseaudio-discuss] [PATCH 07/15] sink-input, source-output: Don't do anything when killing unlinked streams

Tanu Kaskinen tanu.kaskinen at linux.intel.com
Thu Feb 13 19:35:52 CET 2014


Previously we crashed if someone tried to kill an unlinked stream.
This was not such a big issue, because the streams were marked
unlinked in a relatively late phase of the unlinking process, so even
if someone killed a stream that was already being unlinked, that would
probably have not crashed in the state assertion in
pa_sink_input_kill().

Since the previous commit, however, the streams are marked unlinked
earlier, which guarantees that if someone kills a stream while it's
being unlinked, a crash will occur. Removing the assertion removes
that issue. Of course, we could decide that it's not allowed anyway to
try to kill unlinked streams. That would push the requirement to the
caller to ensure that the stream is not unlinked, and that's not
a particularly useful thing to do.

So, let's allow killing of unlinked streams. It turns out that such
operation isn't really safe. For example, protocol-native.c assumes
that when the kill() callback is called, the stream still has a
pointer to the connection object, but when the stream is being
unlinked, that pointer is NULL. Since making the stream unlinked is
pretty much the entire point of killing a stream, it should be fine
to skip calling the kill() callback if the stream is already unlinked
anyway, so that's what this patch does.
---
 src/pulsecore/sink-input.c    | 8 +++++++-
 src/pulsecore/source-output.c | 8 +++++++-
 2 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c
index 450f5d3..f10268c 100644
--- a/src/pulsecore/sink-input.c
+++ b/src/pulsecore/sink-input.c
@@ -913,7 +913,13 @@ const char *pa_sink_input_get_description(pa_sink_input *i) {
 void pa_sink_input_kill(pa_sink_input*i) {
     pa_sink_input_assert_ref(i);
     pa_assert_ctl_context();
-    pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
+
+    if (i->state == PA_SINK_INPUT_UNLINKED) {
+        pa_log_debug("Killing sink input %u (already unlinked, this is a no-op).", i->index);
+        return;
+    }
+
+    pa_log_debug("Killing sink input %u.", i->index);
 
     i->kill(i);
 }
diff --git a/src/pulsecore/source-output.c b/src/pulsecore/source-output.c
index 37a4752..942d285 100644
--- a/src/pulsecore/source-output.c
+++ b/src/pulsecore/source-output.c
@@ -809,7 +809,13 @@ const char *pa_source_output_get_description(pa_source_output *o) {
 void pa_source_output_kill(pa_source_output*o) {
     pa_source_output_assert_ref(o);
     pa_assert_ctl_context();
-    pa_assert(PA_SOURCE_OUTPUT_IS_LINKED(o->state));
+
+    if (o->state == PA_SOURCE_OUTPUT_UNLINKED) {
+        pa_log_debug("Killing source output %u (already unlinked, this is a no-op).", o->index);
+        return;
+    }
+
+    pa_log_debug("Killing source output %u.", o->index);
 
     o->kill(o);
 }
-- 
1.8.3.1



More information about the pulseaudio-discuss mailing list