From: Jaroslav Kysela Date: Mon, 11 Oct 2010 08:34:12 +0000 (+0200) Subject: config file processing: rewrite the locking - use one recursive mutex X-Git-Tag: v1.0.24~20 X-Git-Url: https://git.alsa-project.org/?a=commitdiff_plain;h=c6a81e21c0f566c2cf62ff345eefea857925afa7;p=alsa-lib.git config file processing: rewrite the locking - use one recursive mutex Avoid configuration file processing races when multiple threads call the *open() functions together (for example using alsaloop with multiple -T jobs can reproduce this issue). Signed-off-by: Jaroslav Kysela --- diff --git a/src/conf.c b/src/conf.c index 5d8c5c92..8939d62e 100644 --- a/src/conf.c +++ b/src/conf.c @@ -425,6 +425,11 @@ beginning:

#ifndef DOC_HIDDEN +#ifdef HAVE_LIBPTHREAD +static pthread_mutex_t snd_config_update_mutex = + PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; +#endif + struct _snd_config { char *id; snd_config_type_t type; @@ -464,6 +469,25 @@ typedef struct { int ch; } input_t; +#ifdef HAVE_LIBPTHREAD + +static inline void snd_config_lock(void) +{ + pthread_mutex_lock(&snd_config_update_mutex); +} + +static inline void snd_config_unlock(void) +{ + pthread_mutex_unlock(&snd_config_update_mutex); +} + +#else + +static inline void snd_config_lock(void) { } +static inline void snd_config_unlock(void) { } + +#endif + static int safe_strtoll(const char *str, long long *val) { long long v; @@ -3318,6 +3342,7 @@ static int snd_config_hooks(snd_config_t *config, snd_config_t *private_data) if ((err = snd_config_search(config, "@hooks", &n)) < 0) return 0; + snd_config_lock(); snd_config_remove(n); do { hit = 0; @@ -3334,7 +3359,7 @@ static int snd_config_hooks(snd_config_t *config, snd_config_t *private_data) if (i == idx) { err = snd_config_hooks_call(config, n, private_data); if (err < 0) - return err; + goto _err; idx++; hit = 1; } @@ -3343,6 +3368,7 @@ static int snd_config_hooks(snd_config_t *config, snd_config_t *private_data) err = 0; _err: snd_config_delete(n); + snd_config_unlock(); return err; } @@ -3692,10 +3718,6 @@ int snd_config_update_r(snd_config_t **_top, snd_config_update_t **_update, cons return 1; } -#ifdef HAVE_LIBPTHREAD -static pthread_mutex_t snd_config_update_mutex = PTHREAD_MUTEX_INITIALIZER; -#endif - /** * \brief Updates #snd_config by rereading the global configuration files (if needed). * \return 0 if #snd_config was up to date, 1 if #snd_config was @@ -3716,13 +3738,9 @@ int snd_config_update(void) { int err; -#ifdef HAVE_LIBPTHREAD - pthread_mutex_lock(&snd_config_update_mutex); -#endif + snd_config_lock(); err = snd_config_update_r(&snd_config, &snd_config_global_update, NULL); -#ifdef HAVE_LIBPTHREAD - pthread_mutex_unlock(&snd_config_update_mutex); -#endif + snd_config_unlock(); return err; } @@ -3755,18 +3773,14 @@ int snd_config_update_free(snd_config_update_t *update) */ int snd_config_update_free_global(void) { -#ifdef HAVE_LIBPTHREAD - pthread_mutex_lock(&snd_config_update_mutex); -#endif + snd_config_lock(); if (snd_config) snd_config_delete(snd_config); snd_config = NULL; if (snd_config_global_update) snd_config_update_free(snd_config_global_update); snd_config_global_update = NULL; -#ifdef HAVE_LIBPTHREAD - pthread_mutex_unlock(&snd_config_update_mutex); -#endif + snd_config_unlock(); /* FIXME: better to place this in another place... */ snd_dlobj_cache_cleanup(); @@ -4657,7 +4671,7 @@ int snd_config_expand(snd_config_t *config, snd_config_t *root, const char *args snd_config_delete(subs); return err; } - + /** * \brief Searches for a definition in a configuration tree, using * aliases and expanding hooks and arguments. @@ -4707,10 +4721,15 @@ int snd_config_search_definition(snd_config_t *config, * if key contains dot (.), the implicit base is ignored * and the key starts from root given by the 'config' parameter */ + snd_config_lock(); err = snd_config_search_alias_hooks(config, strchr(key, '.') ? NULL : base, key, &conf); - if (err < 0) + if (err < 0) { + snd_config_unlock(); return err; - return snd_config_expand(conf, config, args, NULL, result); + } + err = snd_config_expand(conf, config, args, NULL, result); + snd_config_unlock(); + return err; } #ifndef DOC_HIDDEN