summaryrefslogtreecommitdiff
path: root/src/pulsecore/source.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pulsecore/source.c')
-rw-r--r--src/pulsecore/source.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c
index a5d5af0b..6308f54d 100644
--- a/src/pulsecore/source.c
+++ b/src/pulsecore/source.c
@@ -235,6 +235,7 @@ pa_source* pa_source_new(
s->flags = flags;
s->priority = 0;
s->suspend_cause = 0;
+ pa_source_set_mixer_dirty(s, FALSE);
s->name = pa_xstrdup(name);
s->proplist = pa_proplist_copy(data->proplist);
s->driver = pa_xstrdup(pa_path_get_filename(data->driver));
@@ -713,6 +714,12 @@ int pa_source_update_status(pa_source*s) {
return source_set_state(s, pa_source_used_by(s) ? PA_SOURCE_RUNNING : PA_SOURCE_IDLE);
}
+/* Called from any context - must be threadsafe */
+void pa_source_set_mixer_dirty(pa_source *s, pa_bool_t is_dirty)
+{
+ pa_atomic_store(&s->mixer_dirty, is_dirty ? 1 : 0);
+}
+
/* Called from main context */
int pa_source_suspend(pa_source *s, pa_bool_t suspend, pa_suspend_cause_t cause) {
pa_source_assert_ref(s);
@@ -728,6 +735,27 @@ int pa_source_suspend(pa_source *s, pa_bool_t suspend, pa_suspend_cause_t cause)
else
s->suspend_cause &= ~cause;
+ if (!(s->suspend_cause & PA_SUSPEND_SESSION) && (pa_atomic_load(&s->mixer_dirty) != 0)) {
+ /* This might look racy but isn't: If somebody sets mixer_dirty exactly here,
+ it'll be handled just fine. */
+ pa_source_set_mixer_dirty(s, FALSE);
+ pa_log_debug("Mixer is now accessible. Updating alsa mixer settings.");
+ if (s->active_port && s->set_port) {
+ if (s->flags & PA_SOURCE_DEFERRED_VOLUME) {
+ struct source_message_set_port msg = { .port = s->active_port, .ret = 0 };
+ pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_SET_PORT, &msg, 0, NULL) == 0);
+ }
+ else
+ s->set_port(s, s->active_port);
+ }
+ else {
+ if (s->set_mute)
+ s->set_mute(s);
+ if (s->set_volume)
+ s->set_volume(s);
+ }
+ }
+
if ((pa_source_get_state(s) == PA_SOURCE_SUSPENDED) == !!s->suspend_cause)
return 0;