artag...@apache.org wrote on Sat, Sep 18, 2010 at 17:54:50 -0000:
> Author: artagnon
> Date: Sat Sep 18 17:54:50 2010
> New Revision: 998502
> 
> URL: http://svn.apache.org/viewvc?rev=998502&view=rev
> Log:
> * subversion/svnrdump/load_editor.c: Attempt to acquire a lock of
>   sorts before attempting to load. This also ensures that
>   pre-revprop-change is enabled before it's too late.
> 
>   (get_lock): Add new function based on the corresponding function in
>   svnsync/main.c. The locking operation can be described as attempting
>   to change a dummy revprop in a delay-loop.
> 
>   (new_revision_record): Before doing anything else, call get_lock and
>   release it at the end of the operations.
> 
> 
> Modified:
>     subversion/trunk/subversion/svnrdump/load_editor.c
> 
> Modified: subversion/trunk/subversion/svnrdump/load_editor.c
> URL: 
> http://svn.apache.org/viewvc/subversion/trunk/subversion/svnrdump/load_editor.c?rev=998502&r1=998501&r2=998502&view=diff
> ==============================================================================
> --- subversion/trunk/subversion/svnrdump/load_editor.c (original)
> +++ subversion/trunk/subversion/svnrdump/load_editor.c Sat Sep 18 17:54:50 
> 2010
> @@ -30,9 +30,15 @@
>  #include "svn_path.h"
>  #include "svn_ra.h"
>  #include "svn_io.h"
> +#include "svn_private_config.h"
> +
> +#include <apr_network_io.h>
>  
>  #include "load_editor.h"
>  
> +#define SVNRDUMP_PROP_LOCK "rdump-lock"

Need SVN_PROP_PREFIX.

> +#define LOCK_RETRIES 10
> +
>  #ifdef SVN_DEBUG
>  #define LDR_DBG(x) SVN_DBG(x)
>  #else
> @@ -50,6 +56,58 @@ commit_callback(const svn_commit_info_t 
>    return SVN_NO_ERROR;
>  }
>  
> +static svn_error_t *
> +get_lock(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;
> +  apr_pool_t *subpool;
> +  int i;
> +
> +  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"));
> +
> +  mylocktoken = svn_string_createf(pool, "%s:%s", hostname_str,
> +                                   svn_uuid_generate(pool));
> +
> +  subpool = svn_pool_create(pool);
> +
> +  for (i = 0; i < LOCK_RETRIES; ++i)
> +    {
> +      svn_pool_clear(subpool);
> +
> +      SVN_ERR(svn_ra_rev_prop(session, 0, SVNRDUMP_PROP_LOCK, 
> &reposlocktoken,
> +                              subpool));
> +
> +      if (reposlocktoken)
> +        {
> +          /* Did we get it? If so, we're done, otherwise we sleep. */
> +          if (strcmp(reposlocktoken->data, mylocktoken->data) == 0)
> +            return SVN_NO_ERROR;
> +          else
> +            {
> +              SVN_ERR(svn_cmdline_printf
> +                      (pool, _("Failed to get lock on destination "
> +                               "repos, currently held by '%s'\n"),
> +                       reposlocktoken->data));
> +
> +              apr_sleep(apr_time_from_sec(1));
> +            }
> +        }
> +      else if (i < LOCK_RETRIES - 1)
> +        {
> +          /* 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));
> +        }
> +    }
> +
> +  return svn_error_createf(APR_EINVAL, NULL,
> +                           _("Couldn't get lock on destination repos "
> +                             "after %d attempts"), i);
> +}

1. Please don't duplicate code.

2. If you do duplicate code, then add big comments (in all instances of
the duplication) pointing to the other instances.

3. Incidentally, I have modified the svnsync instance of this function
on the atomic-revprops branch.  So the desire to avoid duplication isn't
just theoretical in this case...


>  
>  static svn_error_t *
>  new_revision_record(void **revision_baton,
> @@ -539,13 +597,11 @@ drive_dumpstream_loader(svn_stream_t *st
>    struct parse_baton *pb;
>    pb = parse_baton;
>  
> -  /* ### TODO: Figure out if we're allowed to set revprops before
> -     ### we're too late and mess up the repository. svnsync uses some
> -     ### sort of locking mechanism. */
> -
> +  SVN_ERR(get_lock(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));

1. You can't change a property which isn't in the svn:* namespace.

2. Isn't svn_repos_parse_dumpstream2() an expensive function?  You could
do the revprop test before that, in order to (if you have to fail) fail
sooner.

>  
>    return SVN_NO_ERROR;
>  }
> 
> 

Reply via email to