]> git.alsa-project.org Git - alsa-lib.git/commitdiff
conf: fix load_for_all_cards()
authorJaroslav Kysela <perex@perex.cz>
Wed, 2 Jun 2021 06:49:32 +0000 (08:49 +0200)
committerJaroslav Kysela <perex@perex.cz>
Wed, 2 Jun 2021 06:49:32 +0000 (08:49 +0200)
The 63f7745b commit is loading the driver specific configuration
multiple times which ends with the array merges (see the bug).

Introduce the loaded compound which traces the already loaded
driver configurations and skip the multiple load requests.

Fixes: https://github.com/alsa-project/alsa-lib/issues/143
Fixes: 63f7745b ("conf: extend load_for_all_cards hook (id/value table)")
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
src/conf.c

index f6c80031032e39ffe6e1b54e2348f411d30d8a15..d863dec637cf645635bc9f0b1ab3ce21fe8120df 100644 (file)
@@ -4325,18 +4325,23 @@ static int _snd_config_hook_table(snd_config_t *root, snd_config_t *config, snd_
 int snd_config_hook_load_for_all_cards(snd_config_t *root, snd_config_t *config, snd_config_t **dst, snd_config_t *private_data ATTRIBUTE_UNUSED)
 {
        int card = -1, err;
+       snd_config_t *loaded;   // trace loaded cards
        
+       err = snd_config_top(&loaded);
+       if (err < 0)
+               return err;
        do {
                err = snd_card_next(&card);
                if (err < 0)
-                       return err;
+                       goto __fin_err;
                if (card >= 0) {
-                       snd_config_t *n, *private_data = NULL;
+                       snd_config_t *n, *m, *private_data = NULL;
                        const char *driver;
                        char *fdriver = NULL;
+                       bool load;
                        err = snd_determine_driver(card, &fdriver);
                        if (err < 0)
-                               return err;
+                               goto __fin_err;
                        if (snd_config_search(root, fdriver, &n) >= 0) {
                                if (snd_config_get_string(n, &driver) < 0) {
                                        if (snd_config_get_type(n) == SND_CONFIG_TYPE_COMPOUND) {
@@ -4357,6 +4362,19 @@ int snd_config_hook_load_for_all_cards(snd_config_t *root, snd_config_t *config,
                                driver = fdriver;
                        }
                      __std:
+                       load = true;
+                       err = snd_config_imake_integer(&m, driver, 1);
+                       if (err < 0)
+                               goto __err;
+                       err = snd_config_add(loaded, m);
+                       if (err < 0) {
+                               if (err == -EEXIST) {
+                                       snd_config_delete(m);
+                                       load = false;
+                               } else {
+                                       goto __err;
+                               }
+                       }
                        private_data = _snd_config_hook_private_data(card, driver);
                        if (!private_data) {
                                err = -ENOMEM;
@@ -4365,17 +4383,22 @@ int snd_config_hook_load_for_all_cards(snd_config_t *root, snd_config_t *config,
                        err = _snd_config_hook_table(root, config, private_data);
                        if (err < 0)
                                goto __err;
-                       err = snd_config_hook_load(root, config, &n, private_data);
+                       if (load)
+                               err = snd_config_hook_load(root, config, &n, private_data);
                      __err:
                        if (private_data)
                                snd_config_delete(private_data);
                        free(fdriver);
                        if (err < 0)
-                               return err;
+                               goto __fin_err;
                }
        } while (card >= 0);
+       snd_config_delete(loaded);
        *dst = NULL;
        return 0;
+__fin_err:
+       snd_config_delete(loaded);
+       return err;
 }
 #ifndef DOC_HIDDEN
 SND_DLSYM_BUILD_VERSION(snd_config_hook_load_for_all_cards, SND_CONFIG_DLSYM_VERSION_HOOK);