diff options
Diffstat (limited to 'src/pulsecore/source.c')
-rw-r--r-- | src/pulsecore/source.c | 28 |
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; |