alsa-mixer: Drop all unused paths, not only unsupported paths

This is a cleaner solution, because it also removes paths that are
being removed because they are subsets of other paths.

Otherwise, the lingering paths could cause jack detection related
assertion failures.

BugLink: https://bugs.freedesktop.org/show_bug.cgi?id=69676
Reported-and-tested-by: Kalev Lember <kalevlember@gmail.com>
Signed-off-by: David Henningsson <david.henningsson@canonical.com>
This commit is contained in:
David Henningsson 2013-09-23 13:40:26 +02:00
parent 5a5e16bc62
commit 798525bf16

View file

@ -3748,7 +3748,7 @@ fail:
} }
static void mapping_paths_probe(pa_alsa_mapping *m, pa_alsa_profile *profile, static void mapping_paths_probe(pa_alsa_mapping *m, pa_alsa_profile *profile,
pa_alsa_direction_t direction) { pa_alsa_direction_t direction, pa_hashmap *used_paths) {
pa_alsa_path *p; pa_alsa_path *p;
void *state; void *state;
@ -3793,6 +3793,9 @@ static void mapping_paths_probe(pa_alsa_mapping *m, pa_alsa_profile *profile,
if (mixer_handle) if (mixer_handle)
snd_mixer_close(mixer_handle); snd_mixer_close(mixer_handle);
PA_HASHMAP_FOREACH(p, ps->paths, state)
pa_hashmap_put(used_paths, p, p);
pa_log_debug("Available mixer paths (after tidying):"); pa_log_debug("Available mixer paths (after tidying):");
pa_alsa_path_set_dump(ps); pa_alsa_path_set_dump(ps);
} }
@ -4281,16 +4284,18 @@ static snd_pcm_t* mapping_open_pcm(pa_alsa_mapping *m,
&try_buffer_size, 0, NULL, NULL, true); &try_buffer_size, 0, NULL, NULL, true);
} }
static void paths_drop_unsupported(pa_hashmap* h) { static void paths_drop_unused(pa_hashmap* h, pa_hashmap *keep) {
void* state = NULL; void* state = NULL;
const void* key; const void* key;
pa_alsa_path* p; pa_alsa_path* p;
pa_assert(h); pa_assert(h);
pa_assert(keep);
p = pa_hashmap_iterate(h, &state, &key); p = pa_hashmap_iterate(h, &state, &key);
while (p) { while (p) {
if (p->supported <= 0) { if (pa_hashmap_get(keep, p) == NULL) {
pa_hashmap_remove(h, key); pa_hashmap_remove(h, key);
pa_alsa_path_free(p); pa_alsa_path_free(p);
} }
@ -4308,7 +4313,7 @@ void pa_alsa_profile_set_probe(
void *state; void *state;
pa_alsa_profile *p, *last = NULL; pa_alsa_profile *p, *last = NULL;
pa_alsa_mapping *m; pa_alsa_mapping *m;
pa_hashmap *broken_inputs, *broken_outputs; pa_hashmap *broken_inputs, *broken_outputs, *used_paths;
pa_assert(ps); pa_assert(ps);
pa_assert(dev_id); pa_assert(dev_id);
@ -4319,6 +4324,7 @@ void pa_alsa_profile_set_probe(
broken_inputs = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func); broken_inputs = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
broken_outputs = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func); broken_outputs = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
used_paths = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
PA_HASHMAP_FOREACH(p, ps->profiles, state) { PA_HASHMAP_FOREACH(p, ps->profiles, state) {
uint32_t idx; uint32_t idx;
@ -4406,12 +4412,12 @@ void pa_alsa_profile_set_probe(
if (p->output_mappings) if (p->output_mappings)
PA_IDXSET_FOREACH(m, p->output_mappings, idx) PA_IDXSET_FOREACH(m, p->output_mappings, idx)
if (m->output_pcm) if (m->output_pcm)
mapping_paths_probe(m, p, PA_ALSA_DIRECTION_OUTPUT); mapping_paths_probe(m, p, PA_ALSA_DIRECTION_OUTPUT, used_paths);
if (p->input_mappings) if (p->input_mappings)
PA_IDXSET_FOREACH(m, p->input_mappings, idx) PA_IDXSET_FOREACH(m, p->input_mappings, idx)
if (m->input_pcm) if (m->input_pcm)
mapping_paths_probe(m, p, PA_ALSA_DIRECTION_INPUT); mapping_paths_probe(m, p, PA_ALSA_DIRECTION_INPUT, used_paths);
} }
/* Clean up */ /* Clean up */
@ -4419,10 +4425,11 @@ void pa_alsa_profile_set_probe(
pa_alsa_profile_set_drop_unsupported(ps); pa_alsa_profile_set_drop_unsupported(ps);
paths_drop_unsupported(ps->input_paths); paths_drop_unused(ps->input_paths, used_paths);
paths_drop_unsupported(ps->output_paths); paths_drop_unused(ps->output_paths, used_paths);
pa_hashmap_free(broken_inputs); pa_hashmap_free(broken_inputs);
pa_hashmap_free(broken_outputs); pa_hashmap_free(broken_outputs);
pa_hashmap_free(used_paths);
ps->probed = true; ps->probed = true;
} }