]> code.delx.au - pulseaudio/blobdiff - src/modules/alsa/alsa-mixer.c
Use pa_hashmap_remove_and_free() where appropriate
[pulseaudio] / src / modules / alsa / alsa-mixer.c
index 71dfa7975af0b1708183fdf71589d5b6595a83e9..58f91820cbe42e97bc953c6c827d520c92c538b7 100644 (file)
@@ -523,6 +523,7 @@ void pa_alsa_path_free(pa_alsa_path *p) {
     pa_proplist_free(p->proplist);
     pa_xfree(p->name);
     pa_xfree(p->description);
+    pa_xfree(p->description_key);
     pa_xfree(p);
 }
 
@@ -2574,7 +2575,7 @@ static bool element_create_settings(pa_alsa_element *e, pa_alsa_setting *templat
 
         if (template) {
             s = pa_xnewdup(pa_alsa_setting, template, 1);
-            s->options = pa_idxset_copy(template->options);
+            s->options = pa_idxset_copy(template->options, NULL);
             s->name = pa_sprintf_malloc("%s+%s", template->name, o->name);
             s->description =
                 (template->description[0] && o->description[0])
@@ -3748,7 +3749,7 @@ fail:
 }
 
 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;
     void *state;
@@ -3775,8 +3776,8 @@ static void mapping_paths_probe(pa_alsa_mapping *m, pa_alsa_profile *profile,
     pa_assert(pcm_handle);
 
     mixer_handle = pa_alsa_open_mixer_for_pcm(pcm_handle, NULL, &hctl_handle);
-    if (!mixer_handle || !hctl_handle) {
-         /* Cannot open mixer, remove all entries */
+    if (!mixer_handle) {
+        /* Cannot open mixer, remove all entries */
         pa_hashmap_remove_all(ps->paths);
         return;
     }
@@ -3793,6 +3794,9 @@ static void mapping_paths_probe(pa_alsa_mapping *m, pa_alsa_profile *profile,
     if (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_alsa_path_set_dump(ps);
 }
@@ -4281,19 +4285,19 @@ static snd_pcm_t* mapping_open_pcm(pa_alsa_mapping *m,
                               &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;
     const void* key;
     pa_alsa_path* p;
 
     pa_assert(h);
+    pa_assert(keep);
+
     p = pa_hashmap_iterate(h, &state, &key);
     while (p) {
-        if (p->supported <= 0) {
-            pa_hashmap_remove(h, key);
-            pa_alsa_path_free(p);
-        }
+        if (pa_hashmap_get(keep, p) == NULL)
+            pa_hashmap_remove_and_free(h, key);
         p = pa_hashmap_iterate(h, &state, &key);
     }
 }
@@ -4308,7 +4312,7 @@ void pa_alsa_profile_set_probe(
     void *state;
     pa_alsa_profile *p, *last = NULL;
     pa_alsa_mapping *m;
-    pa_hashmap *broken_inputs, *broken_outputs;
+    pa_hashmap *broken_inputs, *broken_outputs, *used_paths;
 
     pa_assert(ps);
     pa_assert(dev_id);
@@ -4319,6 +4323,7 @@ void pa_alsa_profile_set_probe(
 
     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);
+    used_paths = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
 
     PA_HASHMAP_FOREACH(p, ps->profiles, state) {
         uint32_t idx;
@@ -4406,12 +4411,12 @@ void pa_alsa_profile_set_probe(
         if (p->output_mappings)
             PA_IDXSET_FOREACH(m, p->output_mappings, idx)
                 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)
             PA_IDXSET_FOREACH(m, p->input_mappings, idx)
                 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 */
@@ -4419,10 +4424,11 @@ void pa_alsa_profile_set_probe(
 
     pa_alsa_profile_set_drop_unsupported(ps);
 
-    paths_drop_unsupported(ps->input_paths);
-    paths_drop_unsupported(ps->output_paths);
+    paths_drop_unused(ps->input_paths, used_paths);
+    paths_drop_unused(ps->output_paths, used_paths);
     pa_hashmap_free(broken_inputs);
     pa_hashmap_free(broken_outputs);
+    pa_hashmap_free(used_paths);
 
     ps->probed = true;
 }
@@ -4460,17 +4466,13 @@ void pa_alsa_profile_set_drop_unsupported(pa_alsa_profile_set *ps) {
     void *state;
 
     PA_HASHMAP_FOREACH(p, ps->profiles, state) {
-        if (!p->supported) {
-            pa_hashmap_remove(ps->profiles, p->name);
-            profile_free(p);
-        }
+        if (!p->supported)
+            pa_hashmap_remove_and_free(ps->profiles, p->name);
     }
 
     PA_HASHMAP_FOREACH(m, ps->mappings, state) {
-        if (m->supported <= 0) {
-            pa_hashmap_remove(ps->mappings, m->name);
-            mapping_free(m);
-        }
+        if (m->supported <= 0)
+            pa_hashmap_remove_and_free(ps->mappings, m->name);
     }
 }