summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJaroslav Kysela <perex@perex.cz>2021-06-02 08:49:32 +0200
committerJaroslav Kysela <perex@perex.cz>2021-06-02 08:49:32 +0200
commitddfc32abf5697de1618b9e7ffdf57a0f97013090 (patch)
tree5b58923adc8f550ca42a750a84543b3b7f92e6b8
parent9f16fa572947044468695e956a654d4ea07f264f (diff)
downloadalsa-lib-ddfc32abf5697de1618b9e7ffdf57a0f97013090.tar.gz
conf: fix load_for_all_cards()
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>
-rw-r--r--src/conf.c33
1 files changed, 28 insertions, 5 deletions
diff --git a/src/conf.c b/src/conf.c
index f6c80031..d863dec6 100644
--- a/src/conf.c
+++ b/src/conf.c
@@ -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);