Author: philip
Date: Wed Apr 4 13:12:20 2012
New Revision: 1309365
URL: http://svn.apache.org/viewvc?rev=1309365&view=rev
Log:
Fix a refcount/locking bug in BDB.
* subversion/libsvn_fs_base/bdb/env.c
(svn_fs_bdb__close_internal): Change type of parameter, do error_info
processing here.
(svn_fs_bdb__close): Move error_info processing to
svn_fs_bdb__close_internal.
Modified:
subversion/trunk/subversion/libsvn_fs_base/bdb/env.c
Modified: subversion/trunk/subversion/libsvn_fs_base/bdb/env.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_base/bdb/env.c?rev=1309365&r1=1309364&r2=1309365&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_base/bdb/env.c (original)
+++ subversion/trunk/subversion/libsvn_fs_base/bdb/env.c Wed Apr 4 13:12:20
2012
@@ -490,9 +490,29 @@ bdb_close(bdb_env_t *bdb)
static svn_error_t *
-svn_fs_bdb__close_internal(bdb_env_t *bdb)
+svn_fs_bdb__close_internal(bdb_env_baton_t *bdb_baton)
{
svn_error_t *err = SVN_NO_ERROR;
+ bdb_env_t *bdb = bdb_baton->bdb;
+
+ SVN_ERR_ASSERT(bdb_baton->error_info->refcount > 0);
+
+ /* Neutralize bdb_baton's pool cleanup to prevent double-close. See
+ cleanup_env_baton(). */
+ bdb_baton->bdb = NULL;
+
+ /* Note that we only bother with this cleanup if the pool is non-NULL, to
+ guard against potential races between this and the cleanup_env cleanup
+ callback. It's not clear if that can actually happen, but better safe
+ than sorry. */
+ if (0 == --bdb_baton->error_info->refcount && bdb->pool)
+ {
+ svn_error_clear(bdb_baton->error_info->pending_errors);
+#if APR_HAS_THREADS
+ free(bdb_baton->error_info);
+ apr_threadkey_private_set(NULL, bdb->error_info);
+#endif
+ }
if (--bdb->refcount != 0)
{
@@ -520,29 +540,10 @@ svn_fs_bdb__close_internal(bdb_env_t *bd
svn_error_t *
svn_fs_bdb__close(bdb_env_baton_t *bdb_baton)
{
- bdb_env_t *bdb = bdb_baton->bdb;
-
SVN_ERR_ASSERT(bdb_baton->env == bdb_baton->bdb->env);
- /* Neutralize bdb_baton's pool cleanup to prevent double-close. See
- cleanup_env_baton(). */
- bdb_baton->bdb = NULL;
-
- /* Note that we only bother with this cleanup if the pool is non-NULL, to
- guard against potential races between this and the cleanup_env cleanup
- callback. It's not clear if that can actually happen, but better safe
- than sorry. */
- if (0 == --bdb_baton->error_info->refcount && bdb->pool)
- {
- svn_error_clear(bdb_baton->error_info->pending_errors);
-#if APR_HAS_THREADS
- free(bdb_baton->error_info);
- apr_threadkey_private_set(NULL, bdb->error_info);
-#endif
- }
-
/* This may run during final pool cleanup when the lock is NULL. */
- SVN_MUTEX__WITH_LOCK(bdb_cache_lock, svn_fs_bdb__close_internal(bdb));
+ SVN_MUTEX__WITH_LOCK(bdb_cache_lock, svn_fs_bdb__close_internal(bdb_baton));
return SVN_NO_ERROR;
}