Alien-SVN
view release on metacpan or search on metacpan
src/subversion/subversion/libsvn_fs_base/bdb/env.c view on Meta::CPAN
int db_err;
bdb_env_t *bdb;
const char *path_bdb;
char *tmp_path, *tmp_path_bdb;
apr_size_t path_size, path_bdb_size;
#if SVN_BDB_PATH_UTF8
path_bdb = svn_dirent_local_style(path, pool);
#else
SVN_ERR(svn_utf_cstring_from_utf8(&path_bdb,
svn_dirent_local_style(path, pool),
pool));
#endif
/* Allocate the whole structure, including strings, from the heap,
because it must survive the cache pool cleanup. */
path_size = strlen(path) + 1;
path_bdb_size = strlen(path_bdb) + 1;
/* Using calloc() to ensure the padding bytes in bdb->key (which is used as
* a hash key) are zeroed. */
bdb = calloc(1, sizeof(*bdb) + path_size + path_bdb_size);
/* We must initialize this now, as our callers may assume their bdb
pointer is valid when checking for errors. */
apr_pool_cleanup_register(pool, bdb, cleanup_env, apr_pool_cleanup_null);
apr_cpystrn(bdb->errpfx_string, BDB_ERRPFX_STRING,
sizeof(bdb->errpfx_string));
bdb->path = tmp_path = (char*)(bdb + 1);
bdb->path_bdb = tmp_path_bdb = tmp_path + path_size;
apr_cpystrn(tmp_path, path, path_size);
apr_cpystrn(tmp_path_bdb, path_bdb, path_bdb_size);
bdb->pool = pool;
*bdbp = bdb;
#if APR_HAS_THREADS
{
apr_status_t apr_err = apr_threadkey_private_create(&bdb->error_info,
cleanup_error_info,
pool);
if (apr_err)
return svn_error_create(apr_err, NULL,
"Can't allocate thread-specific storage"
" for the Berkeley DB environment descriptor");
}
#endif /* APR_HAS_THREADS */
db_err = db_env_create(&(bdb->env), 0);
if (!db_err)
{
/* See the documentation at bdb_env_t's definition why the
(char *) cast is safe and why it is done. */
bdb->env->set_errpfx(bdb->env, (char *) bdb);
/* bdb_error_gatherer is in parens to stop macro expansion. */
bdb->env->set_errcall(bdb->env, (bdb_error_gatherer));
/* Needed on Windows in case Subversion and Berkeley DB are using
different C runtime libraries */
db_err = bdb->env->set_alloc(bdb->env, malloc, realloc, free);
/* If we detect a deadlock, select a transaction to abort at
random from those participating in the deadlock. */
if (!db_err)
db_err = bdb->env->set_lk_detect(bdb->env, DB_LOCK_RANDOM);
}
return convert_bdb_error(bdb, db_err);
}
/* The environment descriptor cache. */
/* The global pool used for this cache. */
static apr_pool_t *bdb_cache_pool = NULL;
/* The cache. The items are bdb_env_t structures. */
static apr_hash_t *bdb_cache = NULL;
/* The mutex that protects bdb_cache. */
static svn_mutex__t *bdb_cache_lock = NULL;
/* Cleanup callback to NULL out the cache, so we don't try to use it after
the pool has been cleared during global shutdown. */
static apr_status_t
clear_cache(void *data)
{
bdb_cache = NULL;
bdb_cache_lock = NULL;
return APR_SUCCESS;
}
static volatile svn_atomic_t bdb_cache_state = 0;
static svn_error_t *
bdb_init_cb(void *baton, apr_pool_t *pool)
{
bdb_cache_pool = svn_pool_create(pool);
bdb_cache = apr_hash_make(bdb_cache_pool);
SVN_ERR(svn_mutex__init(&bdb_cache_lock, TRUE, bdb_cache_pool));
apr_pool_cleanup_register(bdb_cache_pool, NULL, clear_cache,
apr_pool_cleanup_null);
return SVN_NO_ERROR;
}
svn_error_t *
svn_fs_bdb__init(apr_pool_t* pool)
{
return svn_atomic__init_once(&bdb_cache_state, bdb_init_cb, NULL, pool);
}
/* Construct a cache key for the BDB environment at PATH in *KEYP.
if DBCONFIG_FILE is not NULL, return the opened file handle.
Allocate from POOL. */
static svn_error_t *
bdb_cache_key(bdb_env_key_t *keyp, apr_file_t **dbconfig_file,
const char *path, apr_pool_t *pool)
{
const char *dbcfg_file_name = svn_dirent_join(path, BDB_CONFIG_FILE, pool);
apr_file_t *dbcfg_file;
( run in 0.872 second using v1.01-cache-2.11-cpan-754626df90b )