diff options
-rw-r--r-- | src/pulsecore/sink-input.c | 3 | ||||
-rw-r--r-- | src/pulsecore/sink.c | 7 | ||||
-rw-r--r-- | src/pulsecore/sink.h | 6 | ||||
-rw-r--r-- | src/pulsecore/source-output.c | 3 | ||||
-rw-r--r-- | src/pulsecore/source.c | 5 | ||||
-rw-r--r-- | src/pulsecore/source.h | 6 |
6 files changed, 27 insertions, 3 deletions
diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c index 8ec63b5da..843297f6c 100644 --- a/src/pulsecore/sink-input.c +++ b/src/pulsecore/sink-input.c @@ -1538,6 +1538,9 @@ bool pa_sink_input_may_move_to(pa_sink_input *i, pa_sink *dest) { if (dest == i->sink) return true; + if (dest->unlink_requested) + return false; + if (!pa_sink_input_may_move(i)) return false; diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c index 0b44fc726..3f1ef725b 100644 --- a/src/pulsecore/sink.c +++ b/src/pulsecore/sink.c @@ -676,9 +676,10 @@ void pa_sink_unlink(pa_sink* s) { * reversing pa_sink_put(). It also undoes the registrations * already done in pa_sink_new()! */ - /* All operations here shall be idempotent, i.e. pa_sink_unlink() - * may be called multiple times on the same sink without bad - * effects. */ + if (s->unlink_requested) + return; + + s->unlink_requested = true; linked = PA_SINK_IS_LINKED(s->state); diff --git a/src/pulsecore/sink.h b/src/pulsecore/sink.h index 5df109e55..b64a6665a 100644 --- a/src/pulsecore/sink.h +++ b/src/pulsecore/sink.h @@ -63,6 +63,12 @@ struct pa_sink { pa_core *core; pa_sink_state_t state; + + /* Set in the beginning of pa_sink_unlink() before setting the sink state + * to UNLINKED. The purpose is to prevent moving streams to a sink that is + * about to be removed. */ + bool unlink_requested; + pa_sink_flags_t flags; pa_suspend_cause_t suspend_cause; diff --git a/src/pulsecore/source-output.c b/src/pulsecore/source-output.c index 9217ad462..6d54ae826 100644 --- a/src/pulsecore/source-output.c +++ b/src/pulsecore/source-output.c @@ -1187,6 +1187,9 @@ bool pa_source_output_may_move_to(pa_source_output *o, pa_source *dest) { if (dest == o->source) return true; + if (dest->unlink_requested) + return false; + if (!pa_source_output_may_move(o)) return false; diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c index f4b96ab88..98374ae92 100644 --- a/src/pulsecore/source.c +++ b/src/pulsecore/source.c @@ -618,6 +618,11 @@ void pa_source_unlink(pa_source *s) { /* See pa_sink_unlink() for a couple of comments how this function * works. */ + if (s->unlink_requested) + return; + + s->unlink_requested = true; + linked = PA_SOURCE_IS_LINKED(s->state); if (linked) diff --git a/src/pulsecore/source.h b/src/pulsecore/source.h index 19fb41bd5..91e8674b7 100644 --- a/src/pulsecore/source.h +++ b/src/pulsecore/source.h @@ -64,6 +64,12 @@ struct pa_source { pa_core *core; pa_source_state_t state; + + /* Set in the beginning of pa_source_unlink() before setting the source + * state to UNLINKED. The purpose is to prevent moving streams to a source + * that is about to be removed. */ + bool unlink_requested; + pa_source_flags_t flags; pa_suspend_cause_t suspend_cause; |