You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by da...@apache.org on 2010/09/21 17:21:42 UTC
svn commit: r999461 -
/subversion/branches/atomic-revprop/subversion/svnrdump/load_editor.c
Author: danielsh
Date: Tue Sep 21 15:21:29 2010
New Revision: 999461
URL: http://svn.apache.org/viewvc?rev=999461&view=rev
Log:
On the atomic-revprops branch:
In svnrdump, grab the lock atomically, if possible.
(This was done for svnsync in r999421.)
* subversion/svnsync/main.c
(is_atomicity_error): New helper.
(get_lock):
Take advantage of SVN_RA_CAPABILITY_ATOMIC_REVPROPS if present.
Grow output LOCK_STRING_P parameter.
(drive_dumpstream_loader):
Remove the lock atomically.
Modified:
subversion/branches/atomic-revprop/subversion/svnrdump/load_editor.c
Modified: subversion/branches/atomic-revprop/subversion/svnrdump/load_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/atomic-revprop/subversion/svnrdump/load_editor.c?rev=999461&r1=999460&r2=999461&view=diff
==============================================================================
--- subversion/branches/atomic-revprop/subversion/svnrdump/load_editor.c (original)
+++ subversion/branches/atomic-revprop/subversion/svnrdump/load_editor.c Tue Sep 21 15:21:29 2010
@@ -56,6 +56,12 @@ commit_callback(const svn_commit_info_t
return SVN_NO_ERROR;
}
+/* See subversion/svnsync/main.c for docstring */
+static svn_boolean_t is_atomicity_error(svn_error_t *err)
+{
+ return svn_error_has_cause(err, SVN_ERR_FS_PROP_BASEVALUE_MISMATCH);
+}
+
/* Acquire a lock (of sorts) on the repository associated with the
* given RA SESSION. This lock is just a revprop change attempt in a
* time-delay loop. This function is duplicated by svnsync in main.c.
@@ -65,14 +71,21 @@ commit_callback(const svn_commit_info_t
* applications to avoid duplication.
*/
static svn_error_t *
-get_lock(svn_ra_session_t *session, apr_pool_t *pool)
+get_lock(const svn_string_t **lock_string_p,
+ svn_ra_session_t *session,
+ apr_pool_t *pool)
{
char hostname_str[APRMAXHOSTLEN + 1] = { 0 };
svn_string_t *mylocktoken, *reposlocktoken;
apr_status_t apr_err;
+ svn_boolean_t be_atomic;
apr_pool_t *subpool;
int i;
+ SVN_ERR(svn_ra_has_capability(session, &be_atomic,
+ SVN_RA_CAPABILITY_ATOMIC_REVPROPS,
+ pool));
+
apr_err = apr_gethostname(hostname_str, sizeof(hostname_str), pool);
if (apr_err)
return svn_error_wrap_apr(apr_err, _("Can't get local hostname"));
@@ -80,10 +93,15 @@ get_lock(svn_ra_session_t *session, apr_
mylocktoken = svn_string_createf(pool, "%s:%s", hostname_str,
svn_uuid_generate(pool));
+ /* If we succeed, this is what the property will be set to. */
+ *lock_string_p = mylocktoken;
+
subpool = svn_pool_create(pool);
for (i = 0; i < LOCK_RETRIES; ++i)
{
+ svn_error_t *err;
+
svn_pool_clear(subpool);
SVN_ERR(svn_ra_rev_prop(session, 0, SVNRDUMP_PROP_LOCK, &reposlocktoken,
@@ -106,9 +124,27 @@ get_lock(svn_ra_session_t *session, apr_
}
else if (i < LOCK_RETRIES - 1)
{
+ const svn_string_t *unset = NULL;
+
/* Except in the very last iteration, try to set the lock. */
- SVN_ERR(svn_ra_change_rev_prop(session, 0, SVNRDUMP_PROP_LOCK,
- mylocktoken, subpool));
+ err = svn_ra_change_rev_prop2(session, 0, SVNRDUMP_PROP_LOCK,
+ be_atomic ? &unset : NULL,
+ mylocktoken, subpool);
+
+ if (be_atomic && err && is_atomicity_error(err))
+ /* Someone else has the lock. Let's loop. */
+ svn_error_clear(err);
+ else if (be_atomic && err == SVN_NO_ERROR)
+ /* We have the lock.
+
+ However, for compatibility with concurrent svnsync's that don't
+ support atomicity, loop anyway to double-check that they haven't
+ overwritten our lock.
+ */
+ continue;
+ else
+ /* Genuine error, or we aren't atomic and need to loop. */
+ SVN_ERR(err);
}
}
@@ -602,14 +638,25 @@ drive_dumpstream_loader(svn_stream_t *st
svn_ra_session_t *session,
apr_pool_t *pool)
{
- struct parse_baton *pb;
- pb = parse_baton;
+ struct parse_baton *pb = parse_baton;
+ const svn_string_t *lock_string;
+ svn_boolean_t be_atomic;
+ svn_error_t *err;
+
+ SVN_ERR(svn_ra_has_capability(session, &be_atomic,
+ SVN_RA_CAPABILITY_ATOMIC_REVPROPS,
+ pool));
- SVN_ERR(get_lock(session, pool));
+ SVN_ERR(get_lock(&lock_string, session, pool));
SVN_ERR(svn_ra_get_repos_root2(session, &(pb->root_url), pool));
SVN_ERR(svn_repos_parse_dumpstream2(stream, parser, parse_baton,
NULL, NULL, pool));
- SVN_ERR(svn_ra_change_rev_prop(session, 0, SVNRDUMP_PROP_LOCK, NULL, pool));
+ err = svn_ra_change_rev_prop2(session, 0, SVNRDUMP_PROP_LOCK,
+ be_atomic ? &lock_string : NULL, NULL, pool);
+ if (is_atomicity_error(err))
+ return svn_error_quick_wrap(err,
+ _("\"svnrdump load\"'s lock was stolen; "
+ "can't remove it"));
return SVN_NO_ERROR;
}