diff options
Diffstat (limited to 'subversion/libsvn_subr/dso.c')
-rw-r--r-- | subversion/libsvn_subr/dso.c | 95 |
1 files changed, 39 insertions, 56 deletions
diff --git a/subversion/libsvn_subr/dso.c b/subversion/libsvn_subr/dso.c index e6872c0..7cce2fd 100644 --- a/subversion/libsvn_subr/dso.c +++ b/subversion/libsvn_subr/dso.c @@ -22,14 +22,16 @@ #include <apr_thread_mutex.h> #include <apr_hash.h> +#include "svn_hash.h" #include "svn_dso.h" #include "svn_pools.h" #include "svn_private_config.h" +#include "private/svn_mutex.h" +#include "private/svn_atomic.h" + /* A mutex to protect our global pool and cache. */ -#if APR_HAS_THREADS -static apr_thread_mutex_t *dso_mutex; -#endif +static svn_mutex__t *dso_mutex = NULL; /* Global pool to allocate DSOs in. */ static apr_pool_t *dso_pool; @@ -40,50 +42,40 @@ static apr_hash_t *dso_cache; /* Just an arbitrary location in memory... */ static int not_there_sentinel; +static volatile svn_atomic_t atomic_init_status = 0; + /* A specific value we store in the dso_cache to indicate that the library wasn't found. This keeps us from allocating extra memory from dso_pool when trying to find libraries we already know aren't there. */ #define NOT_THERE ((void *) ¬_there_sentinel) -svn_error_t * -svn_dso_initialize2(void) +static svn_error_t * +atomic_init_func(void *baton, + apr_pool_t *pool) { -#if APR_HAS_THREADS - apr_status_t status; -#endif - if (dso_pool) - return SVN_NO_ERROR; - dso_pool = svn_pool_create(NULL); -#if APR_HAS_THREADS - status = apr_thread_mutex_create(&dso_mutex, - APR_THREAD_MUTEX_DEFAULT, dso_pool); - if (status) - return svn_error_wrap_apr(status, _("Can't create DSO mutex")); -#endif + SVN_ERR(svn_mutex__init(&dso_mutex, TRUE, dso_pool)); dso_cache = apr_hash_make(dso_pool); return SVN_NO_ERROR; } -#if APR_HAS_DSO svn_error_t * -svn_dso_load(apr_dso_handle_t **dso, const char *fname) +svn_dso_initialize2(void) { - apr_status_t status; - - if (! dso_pool) - SVN_ERR(svn_dso_initialize2()); + SVN_ERR(svn_atomic__init_once(&atomic_init_status, atomic_init_func, + NULL, NULL)); -#if APR_HAS_THREADS - status = apr_thread_mutex_lock(dso_mutex); - if (status) - return svn_error_wrap_apr(status, _("Can't grab DSO mutex")); -#endif + return SVN_NO_ERROR; +} - *dso = apr_hash_get(dso_cache, fname, APR_HASH_KEY_STRING); +#if APR_HAS_DSO +static svn_error_t * +svn_dso_load_internal(apr_dso_handle_t **dso, const char *fname) +{ + *dso = svn_hash_gets(dso_cache, fname); /* First check to see if we've been through this before... We do this to avoid calling apr_dso_load multiple times for a given library, @@ -91,52 +83,43 @@ svn_dso_load(apr_dso_handle_t **dso, const char *fname) if (*dso == NOT_THERE) { *dso = NULL; -#if APR_HAS_THREADS - status = apr_thread_mutex_unlock(dso_mutex); - if (status) - return svn_error_wrap_apr(status, _("Can't ungrab DSO mutex")); -#endif return SVN_NO_ERROR; } /* If we got nothing back from the cache, try and load the library. */ if (! *dso) { - status = apr_dso_load(dso, fname, dso_pool); + apr_status_t status = apr_dso_load(dso, fname, dso_pool); if (status) { -#if 0 +#ifdef SVN_DEBUG_DSO char buf[1024]; - fprintf(stderr, "%s\n", apr_dso_error(*dso, buf, 1024)); + fprintf(stderr, + "Dynamic loading of '%s' failed with the following error:\n%s\n", + fname, + apr_dso_error(*dso, buf, 1024)); #endif *dso = NULL; /* It wasn't found, so set the special "we didn't find it" value. */ - apr_hash_set(dso_cache, - apr_pstrdup(dso_pool, fname), - APR_HASH_KEY_STRING, - NOT_THERE); - -#if APR_HAS_THREADS - status = apr_thread_mutex_unlock(dso_mutex); - if (status) - return svn_error_wrap_apr(status, _("Can't ungrab DSO mutex")); -#endif + svn_hash_sets(dso_cache, apr_pstrdup(dso_pool, fname), NOT_THERE); + return SVN_NO_ERROR; } /* Stash the dso so we can use it next time. */ - apr_hash_set(dso_cache, - apr_pstrdup(dso_pool, fname), - APR_HASH_KEY_STRING, - *dso); + svn_hash_sets(dso_cache, apr_pstrdup(dso_pool, fname), *dso); } -#if APR_HAS_THREADS - status = apr_thread_mutex_unlock(dso_mutex); - if (status) - return svn_error_wrap_apr(status, _("Can't ungrab DSO mutex")); -#endif + return SVN_NO_ERROR; +} + +svn_error_t * +svn_dso_load(apr_dso_handle_t **dso, const char *fname) +{ + SVN_ERR(svn_dso_initialize2()); + + SVN_MUTEX__WITH_LOCK(dso_mutex, svn_dso_load_internal(dso, fname)); return SVN_NO_ERROR; } |