You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2010/12/29 22:12:38 UTC

svn commit: r1053735 [2/8] - in /subversion/branches/performance: ./ build/ build/ac-macros/ build/generator/ build/generator/swig/ contrib/client-side/svn_load_dirs/ notes/ subversion/bindings/javahl/native/ subversion/bindings/swig/ subversion/includ...

Modified: subversion/branches/performance/subversion/libsvn_client/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_client/util.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_client/util.c (original)
+++ subversion/branches/performance/subversion/libsvn_client/util.c Wed Dec 29 21:12:33 2010
@@ -34,6 +34,7 @@
 #include "svn_wc.h"
 #include "svn_client.h"
 
+#include "private/svn_client_private.h"
 #include "private/svn_wc_private.h"
 
 #include "client.h"
@@ -320,3 +321,25 @@ svn_cl__rev_default_to_peg(const svn_opt
     return peg_revision;
   return revision;
 }
+
+svn_error_t *
+svn_client__assert_homogeneous_target_type(const apr_array_header_t *targets)
+{
+  svn_boolean_t wc_present = FALSE, url_present = FALSE;
+  int i;
+
+  for (i = 0; i < targets->nelts; ++i)
+    {
+      const char *target = APR_ARRAY_IDX(targets, i, const char *);
+      if (! svn_path_is_url(target))
+        wc_present = TRUE;
+      else
+        url_present = TRUE;
+      if (url_present && wc_present)
+        return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
+                                 _("Cannot mix repository and working copy "
+                                   "targets"));
+    }
+
+  return SVN_NO_ERROR;
+}

Modified: subversion/branches/performance/subversion/libsvn_fs/fs-loader.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_fs/fs-loader.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_fs/fs-loader.c (original)
+++ subversion/branches/performance/subversion/libsvn_fs/fs-loader.c Wed Dec 29 21:12:33 2010
@@ -676,6 +676,7 @@ svn_fs_commit_txn(const char **conflict_
   svn_fs_t *fs;
   const char *fs_path;
 
+  *new_rev = SVN_INVALID_REVNUM;
   SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
   fs = svn_fs_root_fs(txn_root);
   fs_path = svn_fs_path(fs, pool);

Modified: subversion/branches/performance/subversion/libsvn_fs_base/reps-strings.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_fs_base/reps-strings.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_fs_base/reps-strings.c (original)
+++ subversion/branches/performance/subversion/libsvn_fs_base/reps-strings.c Wed Dec 29 21:12:33 2010
@@ -906,10 +906,12 @@ txn_body_read_rep(void *baton, trail_t *
             {
               representation_t *rep;
 
-              svn_checksum_final(&args->rb->md5_checksum,
-                                 args->rb->md5_checksum_ctx, trail->pool);
-              svn_checksum_final(&args->rb->sha1_checksum,
-                                 args->rb->sha1_checksum_ctx, trail->pool);
+              SVN_ERR(svn_checksum_final(&args->rb->md5_checksum,
+                                         args->rb->md5_checksum_ctx,
+                                         trail->pool));
+              SVN_ERR(svn_checksum_final(&args->rb->sha1_checksum,
+                                         args->rb->sha1_checksum_ctx,
+                                         trail->pool));
               args->rb->checksum_finalized = TRUE;
 
               SVN_ERR(svn_fs_bdb__read_rep(&rep, args->rb->fs,

Modified: subversion/branches/performance/subversion/libsvn_fs_base/tree.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_fs_base/tree.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_fs_base/tree.c (original)
+++ subversion/branches/performance/subversion/libsvn_fs_base/tree.c Wed Dec 29 21:12:33 2010
@@ -5365,9 +5365,10 @@ crawl_directory_for_mergeinfo(svn_fs_t *
       void *val;
       svn_pool_clear(iterpool);
       apr_hash_this(hi, &key, NULL, &val);
-      crawl_directory_for_mergeinfo(fs, val,
-                                    svn_fspath__join(node_path, key, iterpool),
-                                    result_catalog, iterpool);
+      SVN_ERR(crawl_directory_for_mergeinfo(fs, val,
+                                            svn_fspath__join(node_path, key,
+                                                             iterpool),
+                                            result_catalog, iterpool));
     }
   svn_pool_destroy(iterpool);
   return SVN_NO_ERROR;

Modified: subversion/branches/performance/subversion/libsvn_fs_base/util/fs_skels.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_fs_base/util/fs_skels.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_fs_base/util/fs_skels.c (original)
+++ subversion/branches/performance/subversion/libsvn_fs_base/util/fs_skels.c Wed Dec 29 21:12:33 2010
@@ -1071,14 +1071,14 @@ svn_fs_base__unparse_representation_skel
 
   /* SHA1 */
   if ((format >= SVN_FS_BASE__MIN_REP_SHARING_FORMAT) && rep->sha1_checksum)
-    prepend_checksum(header_skel, rep->sha1_checksum, pool);
+    SVN_ERR(prepend_checksum(header_skel, rep->sha1_checksum, pool));
 
   /* MD5 */
   {
     svn_checksum_t *md5_checksum = rep->md5_checksum;
     if (! md5_checksum)
       md5_checksum = svn_checksum_create(svn_checksum_md5, pool);
-    prepend_checksum(header_skel, md5_checksum, pool);
+    SVN_ERR(prepend_checksum(header_skel, md5_checksum, pool));
   }
 
   /* TXN */

Modified: subversion/branches/performance/subversion/libsvn_fs_fs/fs_fs.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_fs_fs/fs_fs.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_fs_fs/fs_fs.c (original)
+++ subversion/branches/performance/subversion/libsvn_fs_fs/fs_fs.c Wed Dec 29 21:12:33 2010
@@ -3844,7 +3844,8 @@ rep_read_contents(void *baton,
           svn_checksum_t *md5_checksum;
 
           rb->checksum_finalized = TRUE;
-          svn_checksum_final(&md5_checksum, rb->md5_checksum_ctx, rb->pool);
+          SVN_ERR(svn_checksum_final(&md5_checksum, rb->md5_checksum_ctx,
+                                     rb->pool));
           if (!svn_checksum_match(md5_checksum, rb->md5_checksum))
             return svn_error_createf
               (SVN_ERR_FS_CORRUPT, NULL,
@@ -5800,9 +5801,20 @@ rep_write_contents_close(void *baton)
   /* Check and see if we already have a representation somewhere that's
      identical to the one we just wrote out. */
   if (ffd->rep_sharing_allowed)
-    /* ### TODO: ignore errors opening the DB (issue #3506) * */
-    SVN_ERR(svn_fs_fs__get_rep_reference(&old_rep, b->fs, rep->sha1_checksum,
-                                         b->parent_pool));
+    {
+      svn_error_t *err;
+      err = svn_fs_fs__get_rep_reference(&old_rep, b->fs, rep->sha1_checksum,
+                                         b->parent_pool);
+      if (err)
+        {
+          /* Something's wrong with the rep-sharing index.  We can continue 
+             without rep-sharing, but warn.
+           */
+          (b->fs->warning)(b->fs->warning_baton, err);
+          svn_error_clear(err);
+          old_rep = NULL;
+        }
+    }
   else
     old_rep = NULL;
 
@@ -6029,7 +6041,7 @@ write_hash_rep(svn_filesize_t *size,
   SVN_ERR(svn_hash_write2(hash, stream, SVN_HASH_TERMINATOR, pool));
 
   /* Store the results. */
-  svn_checksum_final(checksum, whb->checksum_ctx, pool);
+  SVN_ERR(svn_checksum_final(checksum, whb->checksum_ctx, pool));
   *size = whb->size;
 
   return svn_stream_printf(whb->stream, pool, "ENDREP\n");
@@ -6585,13 +6597,19 @@ commit_body(void *baton, apr_pool_t *poo
   /* Update the 'current' file. */
   SVN_ERR(write_final_current(cb->fs, cb->txn->id, new_rev, start_node_id,
                               start_copy_id, pool));
+
+  /* At this point the new revision is committed and globally visible
+     so let the caller know it succeeded by giving it the new revision
+     number, which fulfills svn_fs_commit_txn() contract.  Any errors
+     after this point do not change the fact that a new revision was
+     created. */
+  *cb->new_rev_p = new_rev;
+
   ffd->youngest_rev_cache = new_rev;
 
   /* Remove this transaction directory. */
   SVN_ERR(svn_fs_fs__purge_txn(cb->fs, cb->txn->id, pool));
 
-  *cb->new_rev_p = new_rev;
-
   return SVN_NO_ERROR;
 }
 
@@ -6759,7 +6777,8 @@ svn_fs_fs__commit(svn_revnum_t *new_rev_
 
   if (ffd->rep_sharing_allowed)
     {
-      /* ### TODO: ignore errors opening the DB (issue #3506) * */
+      /* At this point, *NEW_REV_P has been set, so errors here won't affect
+         the success of the commit.  (See svn_fs_commit_txn().)  */
       SVN_ERR(svn_fs_fs__open_rep_cache(fs, pool));
       SVN_ERR(svn_sqlite__with_transaction(ffd->rep_cache_db,
                                            commit_sqlite_txn_callback,
@@ -7990,8 +8009,8 @@ pack_shard(const char *revs_dir,
       SVN_ERR(svn_io_stat(&finfo, path, APR_FINFO_SIZE, iterpool));
 
       /* Update the manifest. */
-      svn_stream_printf(manifest_stream, iterpool, "%" APR_OFF_T_FMT "\n",
-                        next_offset);
+      SVN_ERR(svn_stream_printf(manifest_stream, iterpool, "%" APR_OFF_T_FMT
+                                "\n", next_offset));
       next_offset += finfo.size;
 
       /* Copy all the bits from the rev file to the end of the pack file. */
@@ -8099,6 +8118,22 @@ struct pack_baton
   void *cancel_baton;
 };
 
+
+/* The work-horse for svn_fs_fs__pack, called with the FS write lock.
+   This implements the svn_fs_fs__with_write_lock() 'body' callback
+   type.  BATON is a 'struct pack_baton *'.
+   
+   WARNING: if you add a call to this function, please note:
+     The code currently assumes that any piece of code running with
+     the write-lock set can rely on the ffd->min_unpacked_rev and
+     ffd->min_unpacked_revprop caches to be up-to-date (and, by
+     extension, on not having to use a retry when calling
+     svn_fs_fs__path_rev_absolute() and friends).  If you add a call
+     to this function, consider whether you have to call
+     update_min_unpacked_rev() and update_min_unpacked_revprop()
+     afterwards.
+     See this thread: http://thread.gmane.org/1291206765.3782.3309.camel@edith
+ */
 static svn_error_t *
 pack_body(void *baton,
           apr_pool_t *pool)

Modified: subversion/branches/performance/subversion/libsvn_fs_fs/lock.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_fs_fs/lock.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_fs_fs/lock.c (original)
+++ subversion/branches/performance/subversion/libsvn_fs_fs/lock.c Wed Dec 29 21:12:33 2010
@@ -60,16 +60,18 @@
 
 /*** Generic helper functions. ***/
 
-/* Return the MD5 hash of STR. */
-static const char *
-make_digest(const char *str,
+/* Set *DIGEST to the MD5 hash of STR. */
+static svn_error_t *
+make_digest(const char **digest,
+            const char *str,
             apr_pool_t *pool)
 {
   svn_checksum_t *checksum;
 
-  svn_checksum(&checksum, svn_checksum_md5, str, strlen(str), pool);
+  SVN_ERR(svn_checksum(&checksum, svn_checksum_md5, str, strlen(str), pool));
 
-  return svn_checksum_to_cstring_display(checksum, pool);
+  *digest = svn_checksum_to_cstring_display(checksum, pool);
+  return SVN_NO_ERROR;
 }
 
 
@@ -134,18 +136,22 @@ digest_path_from_digest(const char *fs_p
 }
 
 
-/* Return the path to the lock/entries digest file associate with
-   PATH, where PATH is the path to the lock file or lock entries file
+/* Set *DIGEST_PATH to the path to the lock/entries digest file associate
+   with PATH, where PATH is the path to the lock file or lock entries file
    in FS. */
-static const char *
-digest_path_from_path(const char *fs_path,
+static svn_error_t *
+digest_path_from_path(const char **digest_path,
+                      const char *fs_path,
                       const char *path,
                       apr_pool_t *pool)
 {
-  const char *digest = make_digest(path, pool);
-  return svn_dirent_join_many(pool, fs_path, PATH_LOCKS_DIR,
-                              apr_pstrmemdup(pool, digest, DIGEST_SUBDIR_LEN),
-                              digest, NULL);
+  const char *digest;
+  SVN_ERR(make_digest(&digest, path, pool));
+  *digest_path = svn_dirent_join_many(pool, fs_path, PATH_LOCKS_DIR,
+                                      apr_pstrmemdup(pool, digest,
+                                                     DIGEST_SUBDIR_LEN),
+                                      digest, NULL);
+  return SVN_NO_ERROR;
 }
 
 
@@ -362,7 +368,8 @@ set_lock(const char *fs_path,
 
       /* Calculate the DIGEST_PATH for the currently FS path, and then
          get its DIGEST_FILE basename. */
-      digest_path = digest_path_from_path(fs_path, this_path->data, subpool);
+      SVN_ERR(digest_path_from_path(&digest_path, fs_path, this_path->data,
+                                    subpool));
       digest_file = svn_dirent_basename(digest_path, subpool);
 
       SVN_ERR(read_digest_file(&this_children, &this_lock, fs_path,
@@ -389,10 +396,10 @@ set_lock(const char *fs_path,
                                 digest_path, perms_reference, subpool));
 
       /* Prep for next iteration, or bail if we're done. */
-      if (svn_dirent_is_root(this_path->data, this_path->len))
+      if (svn_uri_is_root(this_path->data, this_path->len))
         break;
       svn_stringbuf_set(this_path,
-                        svn_dirent_dirname(this_path->data, subpool));
+                        svn_fspath__dirname(this_path->data, subpool));
     }
 
   svn_pool_destroy(subpool);
@@ -424,7 +431,8 @@ delete_lock(svn_fs_t *fs,
 
       /* Calculate the DIGEST_PATH for the currently FS path, and then
          get its DIGEST_FILE basename. */
-      digest_path = digest_path_from_path(fs->path, this_path->data, subpool);
+      SVN_ERR(digest_path_from_path(&digest_path, fs->path, this_path->data,
+                                    subpool));
       digest_file = svn_dirent_basename(digest_path, subpool);
 
       SVN_ERR(read_digest_file(&this_children, &this_lock, fs->path,
@@ -456,10 +464,10 @@ delete_lock(svn_fs_t *fs,
         }
 
       /* Prep for next iteration, or bail if we're done. */
-      if (svn_dirent_is_root(this_path->data, this_path->len))
+      if (svn_uri_is_root(this_path->data, this_path->len))
         break;
       svn_stringbuf_set(this_path,
-                        svn_dirent_dirname(this_path->data, subpool));
+                        svn_fspath__dirname(this_path->data, subpool));
     }
 
   svn_pool_destroy(subpool);
@@ -478,7 +486,9 @@ get_lock(svn_lock_t **lock_p,
          apr_pool_t *pool)
 {
   svn_lock_t *lock;
-  const char *digest_path = digest_path_from_path(fs->path, path, pool);
+  const char *digest_path;
+
+  SVN_ERR(digest_path_from_path(&digest_path, fs->path, path, pool));
 
   SVN_ERR(read_digest_file(NULL, &lock, fs->path, digest_path, pool));
   if (! lock)
@@ -702,7 +712,8 @@ svn_fs_fs__allow_locked_operation(const 
   if (recurse)
     {
       /* Discover all locks at or below the path. */
-      const char *digest_path = digest_path_from_path(fs->path, path, pool);
+      const char *digest_path;
+      SVN_ERR(digest_path_from_path(&digest_path, fs->path, path, pool));
       SVN_ERR(walk_locks(fs, digest_path, get_locks_callback,
                          fs, have_write_lock, pool));
     }
@@ -1052,7 +1063,7 @@ svn_fs_fs__get_locks(svn_fs_t *fs,
   glfb.get_locks_baton = get_locks_baton;
 
   /* Get the top digest path in our tree of interest, and then walk it. */
-  digest_path = digest_path_from_path(fs->path, path, pool);
+  SVN_ERR(digest_path_from_path(&digest_path, fs->path, path, pool));
   SVN_ERR(walk_locks(fs, digest_path, get_locks_filter_func, &glfb,
                      FALSE, pool));
   return SVN_NO_ERROR;

Modified: subversion/branches/performance/subversion/libsvn_fs_fs/rep-cache.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_fs_fs/rep-cache.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_fs_fs/rep-cache.c (original)
+++ subversion/branches/performance/subversion/libsvn_fs_fs/rep-cache.c Wed Dec 29 21:12:33 2010
@@ -72,8 +72,9 @@ svn_fs_fs__open_rep_cache(svn_fs_t *fs,
                           apr_pool_t *pool)
 {
   fs_fs_data_t *ffd = fs->fsap_data;
-  return svn_error_return(svn_atomic__init_once(&ffd->rep_cache_db_opened,
-                                                open_rep_cache, fs, pool));
+  svn_error_t *err = svn_atomic__init_once(&ffd->rep_cache_db_opened,
+                                           open_rep_cache, fs, pool);
+  return svn_error_quick_wrap(err, _("Couldn't open rep-cache database"));
 }
 
 svn_error_t *

Modified: subversion/branches/performance/subversion/libsvn_fs_fs/tree.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_fs_fs/tree.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_fs_fs/tree.c (original)
+++ subversion/branches/performance/subversion/libsvn_fs_fs/tree.c Wed Dec 29 21:12:33 2010
@@ -1447,18 +1447,18 @@ merge(svn_stringbuf_t *conflict_p,
              a modification. In any of these cases, flag a conflict. */
           if (s_entry == NULL || t_entry == NULL)
             return conflict_err(conflict_p,
-                                svn_dirent_join(target_path,
-                                                a_entry->name,
-                                                iterpool));
+                                svn_fspath__join(target_path,
+                                                 a_entry->name,
+                                                 iterpool));
 
           /* If any of the three entries is of type file, flag a conflict. */
           if (s_entry->kind == svn_node_file
               || t_entry->kind == svn_node_file
               || a_entry->kind == svn_node_file)
             return conflict_err(conflict_p,
-                                svn_dirent_join(target_path,
-                                                a_entry->name,
-                                                iterpool));
+                                svn_fspath__join(target_path,
+                                                 a_entry->name,
+                                                 iterpool));
 
           /* If either SOURCE-ENTRY or TARGET-ENTRY is not a direct
              modification of ANCESTOR-ENTRY, declare a conflict. */
@@ -1471,9 +1471,9 @@ merge(svn_stringbuf_t *conflict_p,
               || strcmp(svn_fs_fs__id_copy_id(t_entry->id),
                         svn_fs_fs__id_copy_id(a_entry->id)) != 0)
             return conflict_err(conflict_p,
-                                svn_dirent_join(target_path,
-                                                a_entry->name,
-                                                iterpool));
+                                svn_fspath__join(target_path,
+                                                 a_entry->name,
+                                                 iterpool));
 
           /* Direct modifications were made to the directory
              ANCESTOR-ENTRY in both SOURCE and TARGET.  Recursively
@@ -1484,7 +1484,7 @@ merge(svn_stringbuf_t *conflict_p,
                                           t_entry->id, iterpool));
           SVN_ERR(svn_fs_fs__dag_get_node(&a_ent_node, fs,
                                           a_entry->id, iterpool));
-          new_tpath = svn_dirent_join(target_path, t_entry->name, iterpool);
+          new_tpath = svn_fspath__join(target_path, t_entry->name, iterpool);
           SVN_ERR(merge(conflict_p, new_tpath,
                         t_ent_node, s_ent_node, a_ent_node,
                         txn_id,
@@ -1520,9 +1520,9 @@ merge(svn_stringbuf_t *conflict_p,
       /* If NAME exists in TARGET, declare a conflict. */
       if (t_entry)
         return conflict_err(conflict_p,
-                            svn_dirent_join(target_path,
-                                            t_entry->name,
-                                            iterpool));
+                            svn_fspath__join(target_path,
+                                             t_entry->name,
+                                             iterpool));
 
       SVN_ERR(svn_fs_fs__dag_get_node(&s_ent_node, fs,
                                       s_entry->id, iterpool));

Modified: subversion/branches/performance/subversion/libsvn_ra/compat.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_ra/compat.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_ra/compat.c (original)
+++ subversion/branches/performance/subversion/libsvn_ra/compat.c Wed Dec 29 21:12:33 2010
@@ -763,12 +763,12 @@ svn_ra__file_revs_from_log(svn_ra_sessio
       currpool = lastpool;
       lastpool = tmppool;
 
-      svn_stream_close(last_stream);
+      SVN_ERR(svn_stream_close(last_stream));
       last_stream = stream;
       last_props = props;
     }
 
-  svn_stream_close(last_stream);
+  SVN_ERR(svn_stream_close(last_stream));
   svn_pool_destroy(currpool);
   svn_pool_destroy(lastpool);
 

Modified: subversion/branches/performance/subversion/libsvn_ra/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_ra/util.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_ra/util.c (original)
+++ subversion/branches/performance/subversion/libsvn_ra/util.c Wed Dec 29 21:12:33 2010
@@ -25,8 +25,10 @@
 
 /*** Includes. ***/
 #include <apr_pools.h>
+#include <apr_network_io.h>
 
 #include "svn_types.h"
+#include "svn_pools.h"
 #include "svn_error.h"
 #include "svn_error_codes.h"
 #include "svn_dirent_uri.h"
@@ -70,3 +72,171 @@ svn_ra__assert_mergeinfo_capable_server(
     }
   return SVN_NO_ERROR;
 }
+
+/* Does ERR mean "the current value of the revprop isn't equal to
+   the *OLD_VALUE_P you gave me"?
+ */
+static svn_boolean_t is_atomicity_error(svn_error_t *err)
+{
+  return svn_error_find_cause(err, SVN_ERR_FS_PROP_BASEVALUE_MISMATCH) != NULL;
+}
+
+svn_error_t *
+svn_ra__release_operational_lock(svn_ra_session_t *session,
+                                 const char *lock_revprop_name,
+                                 const svn_string_t *mylocktoken,
+                                 apr_pool_t *scratch_pool)
+{
+  svn_string_t *reposlocktoken;
+  svn_boolean_t be_atomic;
+
+  SVN_ERR(svn_ra_has_capability(session, &be_atomic,
+                                SVN_RA_CAPABILITY_ATOMIC_REVPROPS,
+                                scratch_pool));
+  SVN_ERR(svn_ra_rev_prop(session, 0, lock_revprop_name,
+                          &reposlocktoken, scratch_pool));
+  if (reposlocktoken && svn_string_compare(reposlocktoken, mylocktoken))
+    {
+      svn_error_t *err;
+      
+      err = svn_ra_change_rev_prop2(session, 0, lock_revprop_name, 
+                                    be_atomic ? &mylocktoken : NULL, NULL,
+                                    scratch_pool);
+      if (is_atomicity_error(err))
+        return svn_error_createf(err->apr_err, err,
+                                 _("Lock was stolen by '%s'; unable to "
+                                   "remove it"), reposlocktoken->data);
+    }
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_ra__get_operational_lock(const svn_string_t **lock_string_p,
+                             const svn_string_t **stolen_lock_p,
+                             svn_ra_session_t *session,
+                             const char *lock_revprop_name,
+                             svn_boolean_t steal_lock,
+                             int num_retries,
+                             svn_ra__lock_retry_func_t retry_func,
+                             void *retry_baton,
+                             svn_cancel_func_t cancel_func,
+                             void *cancel_baton,
+                             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;
+
+  *lock_string_p = NULL;
+  if (stolen_lock_p)
+    *stolen_lock_p = NULL;
+
+  SVN_ERR(svn_ra_has_capability(session, &be_atomic,
+                                SVN_RA_CAPABILITY_ATOMIC_REVPROPS, pool));
+
+  /* We build a lock token from the local hostname and a UUID.  */
+  apr_err = apr_gethostname(hostname_str, sizeof(hostname_str), pool);
+  if (apr_err)
+    return svn_error_wrap_apr(apr_err,
+                              _("Unable to determine local hostname"));
+  mylocktoken = svn_string_createf(pool, "%s:%s", hostname_str,
+                                   svn_uuid_generate(pool));
+
+  /* Ye Olde Retry Loope */
+  subpool = svn_pool_create(pool);
+
+  for (i = 0; i < num_retries; ++i)
+    {
+      svn_error_t *err;
+      const svn_string_t *unset = NULL;
+
+      svn_pool_clear(subpool);
+
+      /* Check for cancellation.  If we're cancelled, don't leave a
+         stray lock behind!  */
+      if (cancel_func)
+        {
+          err = cancel_func(cancel_baton);
+          if (err && err->apr_err == SVN_ERR_CANCELLED)
+            return svn_error_compose_create(
+                       svn_ra__release_operational_lock(session,
+                                                        lock_revprop_name,
+                                                        mylocktoken,
+                                                        subpool),
+                       err);
+          SVN_ERR(err);
+        }
+
+      /* Ask the repository for the value of the LOCK_REVPROP_NAME. */
+      SVN_ERR(svn_ra_rev_prop(session, 0, lock_revprop_name,
+                              &reposlocktoken, subpool));
+
+      /* Did we get a value from the repository?  We'll check to see
+         if it matches our token.  If so, we call it success.  If not
+         and we're told to steal locks, we remember the existing lock
+         token and fall through to the locking code; othewise, we
+         sleep and retry. */
+      if (reposlocktoken)
+        {
+          if (svn_string_compare(reposlocktoken, mylocktoken))
+            {
+              *lock_string_p = mylocktoken;
+              return SVN_NO_ERROR;
+            }
+          else if (! steal_lock)
+            {
+              if (retry_func)
+                SVN_ERR(retry_func(retry_baton, reposlocktoken, subpool));
+              apr_sleep(apr_time_from_sec(1));
+              continue;
+            }
+          else
+            {
+              if (stolen_lock_p)
+                *stolen_lock_p = svn_string_dup(reposlocktoken, pool);
+              unset = reposlocktoken;
+            }
+        }
+
+      /* No lock value in the repository, or we plan to steal it?
+         Well, if we've got a spare iteration, we'll try to set the
+         lock.  (We use the spare iteration to verify that we still
+         have the lock after setting it.) */
+      if (i < num_retries - 1)
+        {
+          /* Except in the very last iteration, try to set the lock. */
+          err = svn_ra_change_rev_prop2(session, 0, lock_revprop_name,
+                                        be_atomic ? &unset : NULL,
+                                        mylocktoken, subpool);
+
+          if (be_atomic && err && is_atomicity_error(err))
+            {
+              /* Someone else has the lock.  No problem, we'll loop again. */
+              svn_error_clear(err);
+            }
+          else if (be_atomic && err == SVN_NO_ERROR)
+            {
+              /* Yay!  We have the lock!  However, for compatibility
+                 with concurrent processes that don't support
+                 atomicity, loop anyway to double-check that they
+                 haven't overwritten our lock.
+              */
+              continue;
+            }
+          else
+            {
+              /* We have a genuine error, or aren't atomic and need
+                 to loop.  */
+              SVN_ERR(err);
+            }
+        }
+    }
+
+  return svn_error_createf(APR_EINVAL, NULL,
+                           _("Couldn't get lock on destination repos "
+                             "after %d attempts"), i);
+}

Modified: subversion/branches/performance/subversion/libsvn_ra_local/ra_plugin.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_ra_local/ra_plugin.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_ra_local/ra_plugin.c (original)
+++ subversion/branches/performance/subversion/libsvn_ra_local/ra_plugin.c Wed Dec 29 21:12:33 2010
@@ -416,7 +416,7 @@ svn_ra_local__get_schemes(apr_pool_t *po
 
 /* Do nothing.
  *
- * Why is this acceptable?  As of now, FS warnings are used for only
+ * Why is this acceptable?  FS warnings used to be used for only
  * two things: failures to close BDB repositories and failures to
  * interact with memcached in FSFS (new in 1.6).  In 1.5 and earlier,
  * we did not call svn_fs_set_warning_func in ra_local, which means
@@ -433,6 +433,9 @@ static void
 ignore_warnings(void *baton,
                 svn_error_t *err)
 {
+#ifdef SVN_DEBUG
+  SVN_DBG(("Ignoring FS warning %d\n", err ? err->apr_err : 0));
+#endif
   return;
 }
 

Modified: subversion/branches/performance/subversion/libsvn_ra_serf/commit.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_ra_serf/commit.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_ra_serf/commit.c (original)
+++ subversion/branches/performance/subversion/libsvn_ra_serf/commit.c Wed Dec 29 21:12:33 2010
@@ -525,9 +525,9 @@ get_version_url(const char **checked_in_
           propfind_url = session->repos_url.path;
         }
 
-      svn_ra_serf__deliver_props(&propfind_ctx, props, session, conn,
-                                 propfind_url, base_revision, "0",
-                                 checked_in_props, FALSE, NULL, pool);
+      SVN_ERR(svn_ra_serf__deliver_props(&propfind_ctx, props, session, conn,
+                                         propfind_url, base_revision, "0",
+                                         checked_in_props, FALSE, NULL, pool));
 
       SVN_ERR(svn_ra_serf__wait_for_props(propfind_ctx, session, pool));
 
@@ -2401,9 +2401,9 @@ svn_ra_serf__change_rev_prop(svn_ra_sess
       props = apr_hash_make(pool);
 
       propfind_ctx = NULL;
-      svn_ra_serf__deliver_props(&propfind_ctx, props, commit->session,
-                                 commit->conn, vcc_url, rev, "0",
-                                 checked_in_props, FALSE, NULL, pool);
+      SVN_ERR(svn_ra_serf__deliver_props(&propfind_ctx, props, commit->session,
+                                         commit->conn, vcc_url, rev, "0",
+                                         checked_in_props, FALSE, NULL, pool));
 
       SVN_ERR(svn_ra_serf__wait_for_props(propfind_ctx, commit->session, pool));
 

Modified: subversion/branches/performance/subversion/libsvn_ra_serf/options.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_ra_serf/options.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_ra_serf/options.c (original)
+++ subversion/branches/performance/subversion/libsvn_ra_serf/options.c Wed Dec 29 21:12:33 2010
@@ -494,8 +494,9 @@ svn_ra_serf__exchange_capabilities(svn_r
   svn_error_t *err;
 
   /* This routine automatically fills in serf_sess->capabilities */
-  svn_ra_serf__create_options_req(&opt_ctx, serf_sess, serf_sess->conns[0],
-                                  serf_sess->repos_url.path, pool);
+  SVN_ERR(svn_ra_serf__create_options_req(&opt_ctx, serf_sess,
+                                          serf_sess->conns[0],
+                                          serf_sess->repos_url.path, pool));
 
   err = svn_ra_serf__context_run_wait(
             svn_ra_serf__get_options_done_ptr(opt_ctx), serf_sess, pool);

Modified: subversion/branches/performance/subversion/libsvn_ra_serf/property.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_ra_serf/property.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_ra_serf/property.c (original)
+++ subversion/branches/performance/subversion/libsvn_ra_serf/property.c Wed Dec 29 21:12:33 2010
@@ -990,8 +990,9 @@ svn_ra_serf__get_baseline_info(const cha
         {
           svn_ra_serf__options_context_t *opt_ctx;
 
-          svn_ra_serf__create_options_req(&opt_ctx, session, conn,
-                                          session->repos_url.path, pool);
+          SVN_ERR(svn_ra_serf__create_options_req(&opt_ctx, session, conn,
+                                                  session->repos_url.path,
+                                                  pool));
           SVN_ERR(svn_ra_serf__context_run_wait(
             svn_ra_serf__get_options_done_ptr(opt_ctx), session, pool));
 

Modified: subversion/branches/performance/subversion/libsvn_ra_serf/ra_serf.h
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_ra_serf/ra_serf.h?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_ra_serf/ra_serf.h (original)
+++ subversion/branches/performance/subversion/libsvn_ra_serf/ra_serf.h Wed Dec 29 21:12:33 2010
@@ -883,10 +883,12 @@ svn_ra_serf__define_ns(svn_ra_serf__ns_t
  * Look up @a name in the @a ns_list list for previously declared namespace
  * definitions.
  *
- * @return @a svn_ra_serf__dav_props_t tuple representing the expanded name.
+ * Return (in @a *returned_prop_name) @a svn_ra_serf__dav_props_t tuple
+ * representing the expanded name.
  */
-svn_ra_serf__dav_props_t
-svn_ra_serf__expand_ns(svn_ra_serf__ns_t *ns_list,
+void
+svn_ra_serf__expand_ns(svn_ra_serf__dav_props_t *returned_prop_name,
+                       svn_ra_serf__ns_t *ns_list,
                        const char *name);
 
 /*

Modified: subversion/branches/performance/subversion/libsvn_ra_serf/serf.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_ra_serf/serf.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_ra_serf/serf.c (original)
+++ subversion/branches/performance/subversion/libsvn_ra_serf/serf.c Wed Dec 29 21:12:33 2010
@@ -600,9 +600,10 @@ fetch_path_props(svn_ra_serf__propfind_c
    */
   if (!SVN_IS_VALID_REVNUM(revision))
     {
-      svn_ra_serf__deliver_props(&prop_ctx, props, session, session->conns[0],
-                                 path, revision, "0", desired_props, TRUE,
-                                 NULL, session->pool);
+      SVN_ERR(svn_ra_serf__deliver_props(&prop_ctx, props, session,
+                                         session->conns[0], path, revision,
+                                         "0", desired_props, TRUE, NULL,
+                                         session->pool));
     }
   else
     {
@@ -619,10 +620,10 @@ fetch_path_props(svn_ra_serf__propfind_c
       prop_ctx = NULL;
       path = svn_path_url_add_component2(basecoll_url, relative_url, pool);
       revision = SVN_INVALID_REVNUM;
-      svn_ra_serf__deliver_props(&prop_ctx, props, session, session->conns[0],
-                                 path, revision, "0",
-                                 desired_props, TRUE,
-                                 NULL, session->pool);
+      SVN_ERR(svn_ra_serf__deliver_props(&prop_ctx, props, session,
+                                         session->conns[0], path, revision,
+                                         "0", desired_props, TRUE, NULL,
+                                         session->pool));
     }
 
   if (prop_ctx)

Modified: subversion/branches/performance/subversion/libsvn_ra_serf/update.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_ra_serf/update.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_ra_serf/update.c (original)
+++ subversion/branches/performance/subversion/libsvn_ra_serf/update.c Wed Dec 29 21:12:33 2010
@@ -1189,10 +1189,11 @@ fetch_file(report_context_t *ctx, report
   info->propfind = NULL;
   if (info->fetch_props)
     {
-      svn_ra_serf__deliver_props(&info->propfind, info->props,
-                                 ctx->sess, conn,
-                                 info->url, info->target_rev, "0", all_props,
-                                 FALSE, &ctx->done_propfinds, info->dir->pool);
+      SVN_ERR(svn_ra_serf__deliver_props(&info->propfind, info->props,
+                                         ctx->sess, conn, info->url,
+                                         info->target_rev, "0", all_props,
+                                         FALSE, &ctx->done_propfinds,
+                                         info->dir->pool));
 
       SVN_ERR_ASSERT(info->propfind);
 
@@ -1743,12 +1744,14 @@ end_report(svn_ra_serf__xml_parser_t *pa
           /* Unconditionally set fetch_props now. */
           info->dir->fetch_props = TRUE;
 
-          svn_ra_serf__deliver_props(&info->dir->propfind, info->dir->props,
-                                     ctx->sess,
-                                     ctx->sess->conns[ctx->sess->cur_conn],
-                                     info->dir->url, info->dir->target_rev,
-                                     "0", all_props, FALSE,
-                                     &ctx->done_propfinds, info->dir->pool);
+          SVN_ERR(svn_ra_serf__deliver_props(&info->dir->propfind,
+                                             info->dir->props, ctx->sess,
+                                             ctx->sess->conns[ctx->sess->cur_conn],
+                                             info->dir->url,
+                                             info->dir->target_rev, "0",
+                                             all_props, FALSE,
+                                             &ctx->done_propfinds,
+                                             info->dir->pool));
 
           SVN_ERR_ASSERT(info->dir->propfind);
 

Modified: subversion/branches/performance/subversion/libsvn_ra_serf/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_ra_serf/util.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_ra_serf/util.c (original)
+++ subversion/branches/performance/subversion/libsvn_ra_serf/util.c Wed Dec 29 21:12:33 2010
@@ -1171,7 +1171,7 @@ start_xml(void *userData, const char *ra
 
   svn_ra_serf__define_ns(&parser->state->ns_list, attrs, parser->state->pool);
 
-  name = svn_ra_serf__expand_ns(parser->state->ns_list, raw_name);
+  svn_ra_serf__expand_ns(&name, parser->state->ns_list, raw_name);
 
   parser->error = parser->start(parser, parser->user_data, name, attrs);
 }
@@ -1185,7 +1185,7 @@ end_xml(void *userData, const char *raw_
   if (parser->error)
     return;
 
-  name = svn_ra_serf__expand_ns(parser->state->ns_list, raw_name);
+  svn_ra_serf__expand_ns(&name, parser->state->ns_list, raw_name);
 
   parser->error = parser->end(parser, parser->user_data, name);
 }

Modified: subversion/branches/performance/subversion/libsvn_ra_serf/xml.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_ra_serf/xml.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_ra_serf/xml.c (original)
+++ subversion/branches/performance/subversion/libsvn_ra_serf/xml.c Wed Dec 29 21:12:33 2010
@@ -86,8 +86,9 @@ svn_ra_serf__define_ns(svn_ra_serf__ns_t
  * Look up NAME in the NS_LIST list for previously declared namespace
  * definitions and return a DAV_PROPS_T-tuple that has values.
  */
-svn_ra_serf__dav_props_t
-svn_ra_serf__expand_ns(svn_ra_serf__ns_t *ns_list,
+void
+svn_ra_serf__expand_ns(svn_ra_serf__dav_props_t *returned_prop_name,
+                       svn_ra_serf__ns_t *ns_list,
                        const char *name)
 {
   const char *colon;
@@ -120,7 +121,8 @@ svn_ra_serf__expand_ns(svn_ra_serf__ns_t
       prop_name.name = name;
     }
 
-  return prop_name;
+  *returned_prop_name = prop_name;
+  return;
 }
 
 void

Modified: subversion/branches/performance/subversion/libsvn_ra_svn/client.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_ra_svn/client.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_ra_svn/client.c (original)
+++ subversion/branches/performance/subversion/libsvn_ra_svn/client.c Wed Dec 29 21:12:33 2010
@@ -1063,7 +1063,7 @@ static svn_error_t *ra_svn_get_file(svn_
       svn_checksum_t *checksum;
       const char *hex_digest;
 
-      svn_checksum_final(&checksum, checksum_ctx, pool);
+      SVN_ERR(svn_checksum_final(&checksum, checksum_ctx, pool));
       hex_digest = svn_checksum_to_cstring_display(checksum, pool);
       if (strcmp(hex_digest, expected_checksum) != 0)
         return svn_error_createf

Modified: subversion/branches/performance/subversion/libsvn_repos/commit.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_repos/commit.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_repos/commit.c (original)
+++ subversion/branches/performance/subversion/libsvn_repos/commit.c Wed Dec 29 21:12:33 2010
@@ -38,6 +38,7 @@
 #include "svn_props.h"
 #include "repos.h"
 #include "svn_private_config.h"
+#include "private/svn_repos_private.h"
 
 
 
@@ -644,7 +645,68 @@ change_dir_prop(void *dir_baton,
                                        name, value, pool);
 }
 
+const char *
+svn_repos__post_commit_error_str(svn_error_t *err,
+                                 apr_pool_t *pool)
+{
+  svn_error_t *hook_err1, *hook_err2;
+  const char *msg;
+
+  if (! err)
+    return _("(no error)");
+
+  err = svn_error_purge_tracing(err);
+
+  /* hook_err1 is the SVN_ERR_REPOS_POST_COMMIT_HOOK_FAILED wrapped
+     error from the post-commit script, if any, and hook_err2 should
+     be the original error, but be defensive and handle a case where
+     SVN_ERR_REPOS_POST_COMMIT_HOOK_FAILED doesn't wrap an error. */
+  hook_err1 = svn_error_find_cause(err, SVN_ERR_REPOS_POST_COMMIT_HOOK_FAILED);
+  if (hook_err1 && hook_err1->child)
+    hook_err2 = hook_err1->child;
+  else
+    hook_err2 = hook_err1;
+
+  /* This implementation counts on svn_repos_fs_commit_txn() returning
+     svn_fs_commit_txn() as the parent error with a child
+     SVN_ERR_REPOS_POST_COMMIT_HOOK_FAILED error.  If the parent error
+     is SVN_ERR_REPOS_POST_COMMIT_HOOK_FAILED then there was no error
+     in svn_fs_commit_txn().
+
+     The post-commit hook error message is already self describing, so
+     it can be dropped into an error message without any additional
+     text. */
+  if (hook_err1)
+    {
+      if (err == hook_err1)
+        {
+          if (hook_err2->message)
+            msg = apr_pstrdup(pool, hook_err2->message);
+          else
+            msg = _("post-commit hook failed with no error message");
+        }
+      else
+        {
+          msg = hook_err2->message
+                  ? hook_err2->message
+                  : _("post-commit hook failed with no error message.");
+          msg = apr_psprintf(
+                  pool,
+                  _("post commit FS processing had error '%s' and %s"),
+                  err->message ? err->message : _("(no error message)"),
+                  msg);
+        }
+    }
+  else
+    {
+      msg = apr_psprintf(pool,
+                         _("post-commit FS processing had error '%s'."),
+                         err->message ? err->message
+                                      : _("(no error message)"));
+    }
 
+  return msg;
+}
 
 static svn_error_t *
 close_edit(void *edit_baton,
@@ -654,7 +716,7 @@ close_edit(void *edit_baton,
   svn_revnum_t new_revision = SVN_INVALID_REVNUM;
   svn_error_t *err;
   const char *conflict;
-  char *post_commit_err = NULL;
+  const char *post_commit_err = NULL;
 
   /* If no transaction has been created (ie. if open_root wasn't
      called before close_edit), abort the operation here with an
@@ -667,51 +729,40 @@ close_edit(void *edit_baton,
   err = svn_repos_fs_commit_txn(&conflict, eb->repos,
                                 &new_revision, eb->txn, pool);
 
-  if (err)
+  if (SVN_IS_VALID_REVNUM(new_revision))
     {
-      if (err->apr_err == SVN_ERR_REPOS_POST_COMMIT_HOOK_FAILED)
+      if (err)
         {
           /* If the error was in post-commit, then the commit itself
              succeeded.  In which case, save the post-commit warning
              (to be reported back to the client, who will probably
              display it as a warning) and clear the error. */
-          if (err->child && err->child->message)
-            {
-              svn_error_t *warning_err = err->child;
-#ifdef SVN_ERR__TRACING
-              /* Skip over any trace records.  */
-              while (warning_err->message != NULL
-                     && strcmp(warning_err->message, SVN_ERR__TRACED) == 0)
-                warning_err = warning_err->child;
-#endif
-              post_commit_err = apr_pstrdup(pool, warning_err->message);
-            }
-
+          post_commit_err = svn_repos__post_commit_error_str(err, pool);
           svn_error_clear(err);
           err = SVN_NO_ERROR;
         }
-      else  /* Got a real error -- one that stopped the commit */
-        {
-          /* ### todo: we should check whether it really was a conflict,
-             and return the conflict info if so? */
+    }
+  else
+    {
+      /* ### todo: we should check whether it really was a conflict,
+         and return the conflict info if so? */
 
-          /* If the commit failed, it's *probably* due to a conflict --
-             that is, the txn being out-of-date.  The filesystem gives us
-             the ability to continue diddling the transaction and try
-             again; but let's face it: that's not how the cvs or svn works
-             from a user interface standpoint.  Thus we don't make use of
-             this fs feature (for now, at least.)
-
-             So, in a nutshell: svn commits are an all-or-nothing deal.
-             Each commit creates a new fs txn which either succeeds or is
-             aborted completely.  No second chances;  the user simply
-             needs to update and commit again  :)
-
-             We ignore the possible error result from svn_fs_abort_txn();
-             it's more important to return the original error. */
-          svn_error_clear(svn_fs_abort_txn(eb->txn, pool));
-          return svn_error_return(err);
-        }
+      /* If the commit failed, it's *probably* due to a conflict --
+         that is, the txn being out-of-date.  The filesystem gives us
+         the ability to continue diddling the transaction and try
+         again; but let's face it: that's not how the cvs or svn works
+         from a user interface standpoint.  Thus we don't make use of
+         this fs feature (for now, at least.)
+
+         So, in a nutshell: svn commits are an all-or-nothing deal.
+         Each commit creates a new fs txn which either succeeds or is
+         aborted completely.  No second chances;  the user simply
+         needs to update and commit again  :)
+
+         We ignore the possible error result from svn_fs_abort_txn();
+         it's more important to return the original error. */
+      svn_error_clear(svn_fs_abort_txn(eb->txn, pool));
+      return svn_error_return(err);
     }
 
   /* Pass new revision information to the caller's callback. */
@@ -743,8 +794,8 @@ close_edit(void *edit_baton,
         commit_info->author = author ? author->data : NULL;
         commit_info->post_commit_err = post_commit_err;
         err = (*eb->commit_callback)(commit_info,
-                                      eb->commit_callback_baton,
-                                      pool);
+                                     eb->commit_callback_baton,
+                                     pool);
       }
   }
 

Modified: subversion/branches/performance/subversion/libsvn_repos/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_repos/deprecated.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_repos/deprecated.c (original)
+++ subversion/branches/performance/subversion/libsvn_repos/deprecated.c Wed Dec 29 21:12:33 2010
@@ -718,7 +718,7 @@ svn_repos_load_fs2(svn_repos_t *repos,
                    apr_pool_t *pool)
 {
   return svn_repos_load_fs3(repos, dumpstream, uuid_action, parent_dir,
-                            use_pre_commit_hook, use_post_commit_hook,
+                            use_pre_commit_hook, use_post_commit_hook, FALSE,
                             feedback_stream ? repos_notify_handler : NULL,
                             feedback_stream, cancel_func, cancel_baton, pool);
 }
@@ -804,7 +804,7 @@ svn_repos_get_fs_build_parser2(const svn
                                apr_pool_t *pool)
 {
   return svn_repos_get_fs_build_parser3(parser, parse_baton, repos, use_history,
-                                        uuid_action, parent_dir,
+                                        FALSE, uuid_action, parent_dir,
                                         outstream ? repos_notify_handler : NULL,
                                         outstream, pool);
 }

Modified: subversion/branches/performance/subversion/libsvn_repos/dump.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_repos/dump.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_repos/dump.c (original)
+++ subversion/branches/performance/subversion/libsvn_repos/dump.c Wed Dec 29 21:12:33 2010
@@ -480,8 +480,8 @@ dump_node(struct edit_baton *eb,
         oldhash = apr_hash_make(pool);
       propstring = svn_stringbuf_create_ensure(0, pool);
       propstream = svn_stream_from_stringbuf(propstring, pool);
-      svn_hash_write_incremental(prophash, oldhash, propstream, "PROPS-END",
-                                 pool);
+      SVN_ERR(svn_hash_write_incremental(prophash, oldhash, propstream,
+                                         "PROPS-END", pool));
       SVN_ERR(svn_stream_close(propstream));
       proplen = propstring->len;
       content_length += proplen;
@@ -907,7 +907,7 @@ write_revision_record(svn_stream_t *stre
 
   encoded_prophash = svn_stringbuf_create_ensure(0, pool);
   propstream = svn_stream_from_stringbuf(encoded_prophash, pool);
-  svn_hash_write2(props, propstream, "PROPS-END", pool);
+  SVN_ERR(svn_hash_write2(props, propstream, "PROPS-END", pool));
   SVN_ERR(svn_stream_close(propstream));
 
   /* ### someday write a revision-content-checksum */

Modified: subversion/branches/performance/subversion/libsvn_repos/fs-wrap.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_repos/fs-wrap.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_repos/fs-wrap.c (original)
+++ subversion/branches/performance/subversion/libsvn_repos/fs-wrap.c Wed Dec 29 21:12:33 2010
@@ -33,6 +33,7 @@
 #include "svn_time.h"
 #include "repos.h"
 #include "svn_private_config.h"
+#include "private/svn_repos_private.h"
 #include "private/svn_utf_private.h"
 
 
@@ -45,25 +46,29 @@ svn_repos_fs_commit_txn(const char **con
                         svn_fs_txn_t *txn,
                         apr_pool_t *pool)
 {
-  svn_error_t *err;
+  svn_error_t *err, *err2;
   const char *txn_name;
 
+  *new_rev = SVN_INVALID_REVNUM;
+
   /* Run pre-commit hooks. */
   SVN_ERR(svn_fs_txn_name(&txn_name, txn, pool));
   SVN_ERR(svn_repos__hooks_pre_commit(repos, txn_name, pool));
 
   /* Commit. */
-  SVN_ERR(svn_fs_commit_txn(conflict_p, new_rev, txn, pool));
+  err = svn_fs_commit_txn(conflict_p, new_rev, txn, pool);
+  if (! SVN_IS_VALID_REVNUM(*new_rev))
+    return err;
 
-  /* Run post-commit hooks.   Notice that we're wrapping the error
-     with a -specific- errorcode, so that our caller knows not to try
-     and abort the transaction. */
-  if ((err = svn_repos__hooks_post_commit(repos, *new_rev, pool)))
-    return svn_error_create
-      (SVN_ERR_REPOS_POST_COMMIT_HOOK_FAILED, err,
-       _("Commit succeeded, but post-commit hook failed"));
+  /* Run post-commit hooks. */
+  if ((err2 = svn_repos__hooks_post_commit(repos, *new_rev, pool)))
+    {
+      err2 = svn_error_create
+               (SVN_ERR_REPOS_POST_COMMIT_HOOK_FAILED, err2,
+                _("Commit succeeded, but post-commit hook failed"));
+    }
 
-  return SVN_NO_ERROR;
+  return svn_error_compose_create(err, err2);
 }
 
 
@@ -152,15 +157,10 @@ svn_repos_fs_begin_txn_for_update(svn_fs
 
 /*** Property wrappers ***/
 
-/* Validate that property NAME is valid for use in a Subversion
-   repository; return SVN_ERR_REPOS_BAD_ARGS if it isn't.  For some "svn:"
-   properties, also validate the value, and return SVN_ERR_BAD_PROPERTY_VALUE
-   if it is not valid.
-
-   Use POOL for temporary allocations.
- */
-static svn_error_t *
-validate_prop(const char *name, const svn_string_t *value, apr_pool_t *pool)
+svn_error_t *
+svn_repos__validate_prop(const char *name,
+                         const svn_string_t *value,
+                         apr_pool_t *pool)
 {
   svn_prop_kind_t kind = svn_property_kind(NULL, name);
 
@@ -223,7 +223,7 @@ svn_repos_fs_change_node_prop(svn_fs_roo
                               apr_pool_t *pool)
 {
   /* Validate the property, then call the wrapped function. */
-  SVN_ERR(validate_prop(name, value, pool));
+  SVN_ERR(svn_repos__validate_prop(name, value, pool));
   return svn_fs_change_node_prop(root, path, name, value, pool);
 }
 
@@ -238,7 +238,7 @@ svn_repos_fs_change_txn_props(svn_fs_txn
   for (i = 0; i < txnprops->nelts; i++)
     {
       svn_prop_t *prop = &APR_ARRAY_IDX(txnprops, i, svn_prop_t);
-      SVN_ERR(validate_prop(prop->name, prop->value, pool));
+      SVN_ERR(svn_repos__validate_prop(prop->name, prop->value, pool));
     }
 
   return svn_fs_change_txn_props(txn, txnprops, pool);
@@ -286,7 +286,7 @@ svn_repos_fs_change_rev_prop4(svn_repos_
       const svn_string_t *old_value;
       char action;
 
-      SVN_ERR(validate_prop(name, new_value, pool));
+      SVN_ERR(svn_repos__validate_prop(name, new_value, pool));
 
       /* Fetch OLD_VALUE for svn_fs_change_rev_prop2(). */
       if (old_value_p)

Modified: subversion/branches/performance/subversion/libsvn_repos/hooks.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_repos/hooks.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_repos/hooks.c (original)
+++ subversion/branches/performance/subversion/libsvn_repos/hooks.c Wed Dec 29 21:12:33 2010
@@ -177,56 +177,14 @@ run_hook_cmd(svn_string_t **result,
              apr_file_t *stdin_handle,
              apr_pool_t *pool)
 {
-  apr_file_t *read_errhandle, *write_errhandle, *null_handle;
-  apr_file_t *read_outhandle, *write_outhandle;
+  apr_file_t *null_handle;
   apr_status_t apr_err;
   svn_error_t *err;
   apr_proc_t cmd_proc;
 
-  /* Create a pipe to access stderr of the child. */
-  apr_err = apr_file_pipe_create(&read_errhandle, &write_errhandle, pool);
-  if (apr_err)
-    return svn_error_wrap_apr
-      (apr_err, _("Can't create pipe for hook '%s'"), cmd);
-
-  /* Pipes are inherited by default, but we don't want that, since
-     APR will duplicate the write end of the pipe for the child process.
-     Not closing the read end is harmless, but if the write end is inherited,
-     it will be inherited by grandchildren as well.  This causes problems
-     if a hook script puts long-running jobs in the background.  Even if
-     they redirect stderr to something else, the write end of our pipe will
-     still be open, causing us to block. */
-  apr_err = apr_file_inherit_unset(read_errhandle);
-  if (apr_err)
-    return svn_error_wrap_apr
-      (apr_err, _("Can't make pipe read handle non-inherited for hook '%s'"),
-       cmd);
-
-  apr_err = apr_file_inherit_unset(write_errhandle);
-  if (apr_err)
-    return svn_error_wrap_apr
-      (apr_err, _("Can't make pipe write handle non-inherited for hook '%s'"),
-       cmd);
-
   if (result)
     {
-      /* Create a pipe to access stdout of the child. */
-      apr_err = apr_file_pipe_create(&read_outhandle, &write_outhandle, pool);
-      if (apr_err)
-        return svn_error_wrap_apr
-          (apr_err, _("Can't create pipe for hook '%s'"), cmd);
-
-      apr_err = apr_file_inherit_unset(read_outhandle);
-      if (apr_err)
-        return svn_error_wrap_apr
-          (apr_err,
-           _("Can't make pipe read handle non-inherited for hook '%s'"), cmd);
-
-      apr_err = apr_file_inherit_unset(write_outhandle);
-      if (apr_err)
-        return svn_error_wrap_apr
-          (apr_err,
-           _("Can't make pipe write handle non-inherited for hook '%s'"), cmd);
+      null_handle = NULL;
     }
   else
     {
@@ -238,26 +196,9 @@ run_hook_cmd(svn_string_t **result,
             (apr_err, _("Can't create null stdout for hook '%s'"), cmd);
     }
 
-  err = svn_io_start_cmd(&cmd_proc, ".", cmd, args, FALSE,
-                         stdin_handle, result ? write_outhandle : null_handle,
-                         write_errhandle, pool);
-
-  /* This seems to be done automatically if we pass the third parameter of
-     apr_procattr_child_in/out_set(), but svn_io_run_cmd()'s interface does
-     not support those parameters. We need to close the write end of the
-     pipe so we don't hang on the read end later, if we need to read it. */
-  apr_err = apr_file_close(write_errhandle);
-  if (!err && apr_err)
-    return svn_error_wrap_apr
-      (apr_err, _("Error closing write end of stderr pipe"));
-
-  if (result)
-    {
-      apr_err = apr_file_close(write_outhandle);
-      if (!err && apr_err)
-        return svn_error_wrap_apr
-          (apr_err, _("Error closing write end of stderr pipe"));
-    }
+  err = svn_io_start_cmd2(&cmd_proc, ".", cmd, args, FALSE,
+                          FALSE, stdin_handle, result != NULL, null_handle,
+                          TRUE, NULL, pool);
 
   if (err)
     {
@@ -266,13 +207,13 @@ run_hook_cmd(svn_string_t **result,
     }
   else
     {
-      err = check_hook_result(name, cmd, &cmd_proc, read_errhandle, pool);
+      err = check_hook_result(name, cmd, &cmd_proc, cmd_proc.err, pool);
     }
 
   /* Hooks are fallible, and so hook failure is "expected" to occur at
      times.  When such a failure happens we still want to close the pipe
      and null file */
-  apr_err = apr_file_close(read_errhandle);
+  apr_err = apr_file_close(cmd_proc.err);
   if (!err && apr_err)
     return svn_error_wrap_apr
       (apr_err, _("Error closing read end of stderr pipe"));
@@ -280,8 +221,8 @@ run_hook_cmd(svn_string_t **result,
   if (result)
     {
       svn_stringbuf_t *native_stdout;
-      SVN_ERR(svn_stringbuf_from_aprfile(&native_stdout, read_outhandle, pool));
-      apr_err = apr_file_close(read_outhandle);
+      SVN_ERR(svn_stringbuf_from_aprfile(&native_stdout, cmd_proc.out, pool));
+      apr_err = apr_file_close(cmd_proc.out);
       if (!err && apr_err)
         return svn_error_wrap_apr
           (apr_err, _("Error closing read end of stderr pipe"));

Modified: subversion/branches/performance/subversion/libsvn_repos/load-fs-vtable.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_repos/load-fs-vtable.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_repos/load-fs-vtable.c (original)
+++ subversion/branches/performance/subversion/libsvn_repos/load-fs-vtable.c Wed Dec 29 21:12:33 2010
@@ -52,6 +52,7 @@ struct parse_baton
   svn_fs_t *fs;
 
   svn_boolean_t use_history;
+  svn_boolean_t validate_props;
   svn_boolean_t use_pre_commit_hook;
   svn_boolean_t use_post_commit_hook;
   enum svn_repos_load_uuid uuid_action;
@@ -111,6 +112,44 @@ struct node_baton
 
 /*----------------------------------------------------------------------*/
 
+
+/* Change revision property NAME to VALUE for REVISION in REPOS.  If
+   VALIDATE_PROPS is set, use functions which perform validation of
+   the property value.  Otherwise, bypass those checks. */
+static svn_error_t *
+change_rev_prop(svn_repos_t *repos,
+                svn_revnum_t revision,
+                const char *name,
+                const svn_string_t *value,
+                svn_boolean_t validate_props,
+                apr_pool_t *pool)
+{
+  if (validate_props)
+    return svn_fs_change_rev_prop2(svn_repos_fs(repos), revision, name,
+                                   NULL, value, pool);
+  else
+    return svn_repos_fs_change_rev_prop4(repos, revision, NULL, name,
+                                         NULL, value, FALSE, FALSE,
+                                         NULL, NULL, pool);
+}
+
+/* Change property NAME to VALUE for PATH in TXN_ROOT.  If
+   VALIDATE_PROPS is set, use functions which perform validation of
+   the property value.  Otherwise, bypass those checks. */
+static svn_error_t *
+change_node_prop(svn_fs_root_t *txn_root,
+                 const char *path,
+                 const char *name,
+                 const svn_string_t *value,
+                 svn_boolean_t validate_props,
+                 apr_pool_t *pool)
+{
+  if (validate_props)
+    return svn_repos_fs_change_node_prop(txn_root, path, name, value, pool);
+  else
+    return svn_fs_change_node_prop(txn_root, path, name, value, pool);
+}
+
 /* Prepend the mergeinfo source paths in MERGEINFO_ORIG with PARENT_DIR, and
    return it in *MERGEINFO_VAL. */
 static svn_error_t *
@@ -279,8 +318,9 @@ renumber_mergeinfo_revs(svn_string_t **f
 /** vtable for doing commits to a fs **/
 
 
-static struct node_baton *
-make_node_baton(apr_hash_t *headers,
+static svn_error_t *
+make_node_baton(struct node_baton **node_baton_p,
+                apr_hash_t *headers,
                 struct revision_baton *rb,
                 apr_pool_t *pool)
 {
@@ -344,26 +384,29 @@ make_node_baton(apr_hash_t *headers,
   if ((val = apr_hash_get(headers, SVN_REPOS_DUMPFILE_TEXT_CONTENT_CHECKSUM,
                           APR_HASH_KEY_STRING)))
     {
-      svn_checksum_parse_hex(&nb->result_checksum, svn_checksum_md5, val, pool);
+      SVN_ERR(svn_checksum_parse_hex(&nb->result_checksum, svn_checksum_md5,
+                                     val, pool));
     }
 
   if ((val = apr_hash_get(headers, SVN_REPOS_DUMPFILE_TEXT_DELTA_BASE_CHECKSUM,
                           APR_HASH_KEY_STRING)))
     {
-      svn_checksum_parse_hex(&nb->base_checksum, svn_checksum_md5, val, pool);
+      SVN_ERR(svn_checksum_parse_hex(&nb->base_checksum, svn_checksum_md5, val,
+                                     pool));
     }
 
   if ((val = apr_hash_get(headers, SVN_REPOS_DUMPFILE_TEXT_COPY_SOURCE_CHECKSUM,
                           APR_HASH_KEY_STRING)))
     {
-      svn_checksum_parse_hex(&nb->copy_source_checksum, svn_checksum_md5, val,
-                             pool);
+      SVN_ERR(svn_checksum_parse_hex(&nb->copy_source_checksum,
+                                     svn_checksum_md5, val, pool));
     }
 
   /* What's cool about this dump format is that the parser just
      ignores any unrecognized headers.  :-)  */
 
-  return nb;
+  *node_baton_p = nb;
+  return SVN_NO_ERROR;
 }
 
 static struct revision_baton *
@@ -539,7 +582,7 @@ new_node_record(void **node_baton,
                             _("Malformed dumpstream: "
                               "Revision 0 must not contain node records"));
 
-  nb = make_node_baton(headers, rb, pool);
+  SVN_ERR(make_node_baton(&nb, headers, rb, pool));
 
   /* Make sure we have an action we recognize. */
   if (nb->action < svn_node_action_change
@@ -578,8 +621,7 @@ new_node_record(void **node_baton,
   *node_baton = nb;
   return SVN_NO_ERROR;
 }
-
-
+               
 static svn_error_t *
 set_revision_property(void *baton,
                       const char *name,
@@ -589,7 +631,10 @@ set_revision_property(void *baton,
 
   if (rb->rev > 0)
     {
-      SVN_ERR(svn_fs_change_txn_prop(rb->txn, name, value, rb->pool));
+      if (rb->pb->validate_props)
+        SVN_ERR(svn_repos_fs_change_txn_prop(rb->txn, name, value, rb->pool));
+      else
+        SVN_ERR(svn_fs_change_txn_prop(rb->txn, name, value, rb->pool));
 
       /* Remember any datestamp that passes through!  (See comment in
          close_revision() below.) */
@@ -606,8 +651,8 @@ set_revision_property(void *baton,
       SVN_ERR(svn_fs_youngest_rev(&youngest_rev, pb->fs, rb->pool));
 
       if (youngest_rev == 0)
-        SVN_ERR(svn_fs_change_rev_prop2(pb->fs, 0, name, NULL, value,
-                                        rb->pool));
+        SVN_ERR(change_rev_prop(pb->repos, 0, name, value,
+                                pb->validate_props, rb->pool));
     }
 
   return SVN_NO_ERROR;
@@ -672,8 +717,8 @@ set_node_property(void *baton,
         }
     }
 
-  return svn_fs_change_node_prop(rb->txn_root, nb->path,
-                                 name, value, nb->pool);
+  return change_node_prop(rb->txn_root, nb->path, name, value,
+                          pb->validate_props, nb->pool);
 }
 
 
@@ -684,8 +729,8 @@ delete_node_property(void *baton,
   struct node_baton *nb = baton;
   struct revision_baton *rb = nb->rb;
 
-  return svn_fs_change_node_prop(rb->txn_root, nb->path,
-                                 name, NULL, nb->pool);
+  return change_node_prop(rb->txn_root, nb->path, name, NULL,
+                          rb->pb->validate_props, nb->pool);
 }
 
 
@@ -705,10 +750,8 @@ remove_node_props(void *baton)
       const void *key;
 
       apr_hash_this(hi, &key, NULL, NULL);
-
-      SVN_ERR(svn_fs_change_node_prop(rb->txn_root, nb->path,
-                                      (const char *) key, NULL,
-                                      nb->pool));
+      SVN_ERR(change_node_prop(rb->txn_root, nb->path, key, NULL,
+                               rb->pb->validate_props, nb->pool));
     }
 
   return SVN_NO_ERROR;
@@ -797,7 +840,18 @@ close_revision(void *baton)
     }
 
   /* Commit. */
-  if ((err = svn_fs_commit_txn(&conflict_msg, new_rev, rb->txn, rb->pool)))
+  err = svn_fs_commit_txn(&conflict_msg, new_rev, rb->txn, rb->pool);
+  if (SVN_IS_VALID_REVNUM(*new_rev))
+    {
+      if (err)
+        {
+          /* ### Log any error, but better yet is to rev
+             ### close_revision()'s API to allow both new_rev and err
+             ### to be returned, see #3768. */
+          svn_error_clear(err);
+        }
+    }
+  else
     {
       svn_error_clear(svn_fs_abort_txn(rb->txn, rb->pool));
       if (conflict_msg)
@@ -854,9 +908,8 @@ close_revision(void *baton)
      Note that if rb->datestamp is NULL, that's fine -- if the dump
      data doesn't carry a datestamp, we want to preserve that fact in
      the load. */
-  SVN_ERR(svn_fs_change_rev_prop(pb->fs, *new_rev,
-                                 SVN_PROP_REVISION_DATE, rb->datestamp,
-                                 rb->pool));
+  SVN_ERR(change_rev_prop(pb->repos, *new_rev, SVN_PROP_REVISION_DATE,
+                          rb->datestamp, pb->validate_props, rb->pool));
 
   if (pb->notify_func)
     {
@@ -882,6 +935,7 @@ svn_repos_get_fs_build_parser3(const svn
                                void **parse_baton,
                                svn_repos_t *repos,
                                svn_boolean_t use_history,
+                               svn_boolean_t validate_props,
                                enum svn_repos_load_uuid uuid_action,
                                const char *parent_dir,
                                svn_repos_notify_func_t notify_func,
@@ -906,6 +960,7 @@ svn_repos_get_fs_build_parser3(const svn
   pb->repos = repos;
   pb->fs = svn_repos_fs(repos);
   pb->use_history = use_history;
+  pb->validate_props = validate_props;
   pb->notify_func = notify_func;
   pb->notify_baton = notify_baton;
   pb->notify = svn_repos_notify_create(svn_repos_notify_load_txn_start, pool);
@@ -930,6 +985,7 @@ svn_repos_load_fs3(svn_repos_t *repos,
                    const char *parent_dir,
                    svn_boolean_t use_pre_commit_hook,
                    svn_boolean_t use_post_commit_hook,
+                   svn_boolean_t validate_props,
                    svn_repos_notify_func_t notify_func,
                    void *notify_baton,
                    svn_cancel_func_t cancel_func,
@@ -945,6 +1001,7 @@ svn_repos_load_fs3(svn_repos_t *repos,
   SVN_ERR(svn_repos_get_fs_build_parser3(&parser, &parse_baton,
                                          repos,
                                          TRUE, /* look for copyfrom revs */
+                                         validate_props,
                                          uuid_action,
                                          parent_dir,
                                          notify_func,

Modified: subversion/branches/performance/subversion/libsvn_subr/cache-memcache.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_subr/cache-memcache.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_subr/cache-memcache.c (original)
+++ subversion/branches/performance/subversion/libsvn_subr/cache-memcache.c Wed Dec 29 21:12:33 2010
@@ -75,10 +75,11 @@ struct svn_memcache_t {
                                     2 * APR_MD5_DIGESTSIZE)
 
 
-/* Returns a memcache key for the given key KEY for CACHE, allocated
+/* Set *MC_KEY to a memcache key for the given key KEY for CACHE, allocated
    in POOL. */
-static const char *
-build_key(memcache_t *cache,
+static svn_error_t *
+build_key(const char **mc_key,
+          memcache_t *cache,
           const void *raw_key,
           apr_pool_t *pool)
 {
@@ -111,7 +112,8 @@ build_key(memcache_t *cache,
   if (long_key_len > MEMCACHED_KEY_UNHASHED_LEN)
     {
       svn_checksum_t *checksum;
-      svn_checksum(&checksum, svn_checksum_md5, long_key, long_key_len, pool);
+      SVN_ERR(svn_checksum(&checksum, svn_checksum_md5, long_key, long_key_len,
+                           pool));
 
       long_key = apr_pstrcat(pool,
                              apr_pstrmemdup(pool, long_key,
@@ -120,7 +122,8 @@ build_key(memcache_t *cache,
                              (char *)NULL);
     }
 
-  return long_key;
+  *mc_key = long_key;
+  return SVN_NO_ERROR;
 }
 
 
@@ -138,7 +141,7 @@ memcache_get(void **value_p,
   apr_size_t data_len;
   apr_pool_t *subpool = svn_pool_create(pool);
 
-  mc_key = build_key(cache, key, subpool);
+  SVN_ERR(build_key(&mc_key, cache, key, subpool));
 
   apr_err = apr_memcache_getp(cache->memcache,
                               pool,
@@ -184,10 +187,12 @@ memcache_set(void *cache_void,
   memcache_t *cache = cache_void;
   apr_pool_t *subpool = svn_pool_create(pool);
   char *data;
-  const char *mc_key = build_key(cache, key, subpool);
+  const char *mc_key;
   apr_size_t data_len;
   apr_status_t apr_err;
 
+  SVN_ERR(build_key(&mc_key, cache, key, subpool));
+
   if (cache->serialize_func)
     {
       SVN_ERR((cache->serialize_func)(&data, &data_len, value, subpool));

Modified: subversion/branches/performance/subversion/libsvn_subr/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_subr/deprecated.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_subr/deprecated.c (original)
+++ subversion/branches/performance/subversion/libsvn_subr/deprecated.c Wed Dec 29 21:12:33 2010
@@ -250,6 +250,16 @@ svn_subst_stream_translated_to_normal_fo
 }
 
 svn_error_t *
+svn_subst_translate_string(svn_string_t **new_value,
+                           const svn_string_t *value,
+                           const char *encoding,
+                           apr_pool_t *pool)
+{
+  return svn_subst_translate_string2(new_value, NULL, NULL, value,
+                                     encoding, pool, pool);
+}
+
+svn_error_t *
 svn_subst_stream_detranslated(svn_stream_t **stream_p,
                               const char *src,
                               svn_subst_eol_style_t eol_style,
@@ -754,6 +764,22 @@ svn_io_get_dirents(apr_hash_t **dirents,
   return svn_io_get_dirents2(dirents, path, pool);
 }
 
+svn_error_t *
+svn_io_start_cmd(apr_proc_t *cmd_proc,
+                 const char *path,
+                 const char *cmd,
+                 const char *const *args,
+                 svn_boolean_t inherit,
+                 apr_file_t *infile,
+                 apr_file_t *outfile,
+                 apr_file_t *errfile,
+                 apr_pool_t *pool)
+{
+  return svn_io_start_cmd2(cmd_proc, path, cmd, args, inherit, FALSE,
+                           infile, FALSE, outfile, FALSE, errfile, pool);
+}
+
+
 struct walk_func_filter_baton_t
 {
   svn_io_walk_func_t walk_func;

Modified: subversion/branches/performance/subversion/libsvn_subr/dirent_uri.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_subr/dirent_uri.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_subr/dirent_uri.c (original)
+++ subversion/branches/performance/subversion/libsvn_subr/dirent_uri.c Wed Dec 29 21:12:33 2010
@@ -2144,6 +2144,7 @@ svn_uri_condense_targets(const char **pc
   /* Early exit when there's only one uri to work on. */
   if (targets->nelts == 1)
     {
+      *pcommon = apr_pstrdup(result_pool, *pcommon);
       if (pcondensed_targets)
         *pcondensed_targets = apr_array_make(result_pool, 0,
                                              sizeof(const char *));

Modified: subversion/branches/performance/subversion/libsvn_subr/error.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_subr/error.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_subr/error.c (original)
+++ subversion/branches/performance/subversion/libsvn_subr/error.c Wed Dec 29 21:12:33 2010
@@ -34,34 +34,46 @@
 #include "svn_utf.h"
 
 #ifdef SVN_DEBUG
+/* XXX FIXME: These should be protected by a thread mutex.
+   svn_error__locate and make_error_internal should cooperate
+   in locking and unlocking it. */
+
+/* XXX TODO: Define mutex here #if APR_HAS_THREADS */
+static const char * volatile error_file = NULL;
+static long volatile error_line = -1;
+
 /* file_line for the non-debug case. */
 static const char SVN_FILE_LINE_UNDEFINED[] = "svn:<undefined>";
 #endif /* SVN_DEBUG */
 
 #include "svn_private_config.h"
+#include "private/svn_error_private.h"
 
 
-/*** Helpers for creating errors ***/
+/*
+ * Undefine the helpers for creating errors.
+ *
+ * *NOTE*: Any use of these functions in any other function may need
+ * to call svn_error__locate() because the macro that would otherwise
+ * do this is being undefined and the filename and line number will
+ * not be properly set in the static error_file and error_line
+ * variables.
+ */
 #undef svn_error_create
 #undef svn_error_createf
 #undef svn_error_quick_wrap
 #undef svn_error_wrap_apr
 
-
-/* XXX FIXME: These should be protected by a thread mutex.
-   svn_error__locate and make_error_internal should cooperate
-   in locking and unlocking it. */
-
-/* XXX TODO: Define mutex here #if APR_HAS_THREADS */
-static const char * volatile error_file = NULL;
-static long volatile error_line = -1;
-
+/* Note: This function was historically in the public API, so we need
+ * to define it even when !SVN_DEBUG. */
 void
 svn_error__locate(const char *file, long line)
 {
+#if defined(SVN_DEBUG)
   /* XXX TODO: Lock mutex here */
   error_file = file;
   error_line = line;
+#endif
 }
 
 
@@ -103,11 +115,11 @@ make_error_internal(apr_status_t apr_err
   new_error->apr_err = apr_err;
   new_error->child   = child;
   new_error->pool    = pool;
+#if defined(SVN_DEBUG)
   new_error->file    = error_file;
   new_error->line    = error_line;
   /* XXX TODO: Unlock mutex here */
 
-#if defined(SVN_DEBUG)
   if (! child)
       apr_pool_cleanup_register(pool, new_error,
                                 err_abort,
@@ -269,16 +281,16 @@ svn_error_root_cause(svn_error_t *err)
   return err;
 }
 
-svn_boolean_t
-svn_error_has_cause(svn_error_t *err, apr_status_t apr_err)
+svn_error_t *
+svn_error_find_cause(svn_error_t *err, apr_status_t apr_err)
 {
   svn_error_t *child;
 
   for (child = err; child; child = child->child)
     if (child->apr_err == apr_err)
-      return TRUE;
+      return child;
 
-  return FALSE;
+  return SVN_NO_ERROR;
 }
 
 svn_error_t *
@@ -331,8 +343,8 @@ svn_error_clear(svn_error_t *err)
     }
 }
 
-/* Is ERR a tracing-only error chain link?  */
-static svn_boolean_t is_tracing_link(svn_error_t *err)
+svn_boolean_t
+svn_error__is_tracing_link(svn_error_t *err)
 {
 #ifdef SVN_ERR__TRACING
   /* ### A strcmp()?  Really?  I think it's the best we can do unless
@@ -349,39 +361,46 @@ svn_error_t *
 svn_error_purge_tracing(svn_error_t *err)
 {
 #ifdef SVN_ERR__TRACING
-  svn_error_t *tmp_err = err;
   svn_error_t *new_err = NULL, *new_err_leaf = NULL;
 
   if (! err)
     return SVN_NO_ERROR;
 
-  while (tmp_err)
+  do
     {
+      svn_error_t *tmp_err;
+
       /* Skip over any trace-only links. */
-      while (tmp_err && is_tracing_link(tmp_err))
-        tmp_err = tmp_err->child;
+      while (err && svn_error__is_tracing_link(err))
+        err = err->child;
+
+      /* The link must be a real link in the error chain, otherwise an
+         error chain with trace only links would map into SVN_NO_ERROR. */
+      SVN_ERR_ASSERT(err);
+
+      /* Copy the current error except for its child error pointer
+         into the new error.  Share any message and source filename
+         strings from the error. */
+      tmp_err = apr_palloc(err->pool, sizeof(*tmp_err));
+      *tmp_err = *err;
+      tmp_err->child = NULL;
 
       /* Add a new link to the new chain (creating the chain if necessary). */
       if (! new_err)
         {
           new_err = tmp_err;
-          new_err_leaf = new_err;
+          new_err_leaf = tmp_err;
         }
       else
         {
           new_err_leaf->child = tmp_err;
-          new_err_leaf = new_err_leaf->child;
+          new_err_leaf = tmp_err;
         }
 
       /* Advance to the next link in the original chain. */
-      tmp_err = tmp_err->child;
-    }
+      err = err->child;
+    } while (err);
 
-  /* If we get here, there had better be a real link in this error chain. */
-  SVN_ERR_ASSERT(new_err_leaf);
-
-  /* Tie off the chain, and return its head. */
-  new_err_leaf->child = NULL;
   return new_err;
 #else  /* SVN_ERR__TRACING */
   return err;
@@ -420,7 +439,7 @@ print_error(svn_error_t *err, FILE *stre
 #endif /* SVN_DEBUG */
 
   /* "traced call" */
-  if (is_tracing_link(err))
+  if (svn_error__is_tracing_link(err))
     {
       /* Skip it.  We already printed the file-line coordinates. */
     }
@@ -550,7 +569,7 @@ const char *
 svn_err_best_message(svn_error_t *err, char *buf, apr_size_t bufsize)
 {
   /* Skip over any trace records.  */
-  while (is_tracing_link(err))
+  while (svn_error__is_tracing_link(err))
     err = err->child;
   if (err->message)
     return err->message;
@@ -593,6 +612,11 @@ svn_error_raise_on_malfunction(svn_boole
   if (!can_return)
     abort(); /* Nothing else we can do as a library */
 
+  /* The filename and line number of the error source needs to be set
+     here because svn_error_createf() is not the macro defined in
+     svn_error.h but the real function. */
+  svn_error__locate(file, line);
+
   if (expr)
     return svn_error_createf(SVN_ERR_ASSERTION_FAIL, NULL,
                              _("In file '%s' line %d: assertion failed (%s)"),

Modified: subversion/branches/performance/subversion/libsvn_subr/io.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_subr/io.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_subr/io.c (original)
+++ subversion/branches/performance/subversion/libsvn_subr/io.c Wed Dec 29 21:12:33 2010
@@ -756,7 +756,7 @@ svn_io_copy_file(const char *src,
 #endif
 
   SVN_ERR(svn_io_file_open(&from_file, src, APR_READ | APR_BINARY,
-                         APR_OS_DEFAULT, pool));
+                           APR_OS_DEFAULT, pool));
 
   /* For atomicity, we copy to a tmp file and then rename the tmp
      file over the real destination. */
@@ -2189,15 +2189,18 @@ handle_child_process_error(apr_pool_t *p
 
 
 svn_error_t *
-svn_io_start_cmd(apr_proc_t *cmd_proc,
-                 const char *path,
-                 const char *cmd,
-                 const char *const *args,
-                 svn_boolean_t inherit,
-                 apr_file_t *infile,
-                 apr_file_t *outfile,
-                 apr_file_t *errfile,
-                 apr_pool_t *pool)
+svn_io_start_cmd2(apr_proc_t *cmd_proc,
+                  const char *path,
+                  const char *cmd,
+                  const char *const *args,
+                  svn_boolean_t inherit,
+                  svn_boolean_t infile_pipe,
+                  apr_file_t *infile,
+                  svn_boolean_t outfile_pipe,
+                  apr_file_t *outfile,
+                  svn_boolean_t errfile_pipe,
+                  apr_file_t *errfile,
+                  apr_pool_t *pool)
 {
   apr_status_t apr_err;
   apr_procattr_t *cmdproc_attr;
@@ -2205,6 +2208,10 @@ svn_io_start_cmd(apr_proc_t *cmd_proc,
   const char **args_native;
   const char *cmd_apr;
 
+  SVN_ERR_ASSERT(!((infile != NULL) && infile_pipe));
+  SVN_ERR_ASSERT(!((outfile != NULL) && outfile_pipe));
+  SVN_ERR_ASSERT(!((errfile != NULL) && errfile_pipe));
+
   /* Create the process attributes. */
   apr_err = apr_procattr_create(&cmdproc_attr, pool);
   if (apr_err)
@@ -2213,7 +2220,7 @@ svn_io_start_cmd(apr_proc_t *cmd_proc,
 
   /* Make sure we invoke cmd directly, not through a shell. */
   apr_err = apr_procattr_cmdtype_set(cmdproc_attr,
-                                     inherit?APR_PROGRAM_PATH:APR_PROGRAM);
+                                     inherit ? APR_PROGRAM_PATH : APR_PROGRAM);
   if (apr_err)
     return svn_error_wrap_apr(apr_err, _("Can't set process '%s' cmdtype"),
                               cmd);
@@ -2257,6 +2264,13 @@ svn_io_start_cmd(apr_proc_t *cmd_proc,
           (apr_err, _("Can't set process '%s' child errfile"), cmd);
     }
 
+  /* Forward request for pipes to APR. */
+  if (infile_pipe || outfile_pipe || errfile_pipe)
+    apr_procattr_io_set(cmdproc_attr,
+                        infile_pipe ? APR_FULL_BLOCK : APR_NO_PIPE,
+                        outfile_pipe ? APR_FULL_BLOCK : APR_NO_PIPE,
+                        errfile_pipe ? APR_FULL_BLOCK : APR_NO_PIPE);
+
   /* Have the child print any problems executing its program to errfile. */
   apr_err = apr_pool_userdata_set(errfile, ERRFILE_KEY, NULL, pool);
   if (apr_err)
@@ -2348,8 +2362,9 @@ svn_io_run_cmd(const char *path,
 {
   apr_proc_t cmd_proc;
 
-  SVN_ERR(svn_io_start_cmd(&cmd_proc, path, cmd, args, inherit,
-                           infile, outfile, errfile, pool));
+  SVN_ERR(svn_io_start_cmd2(&cmd_proc, path, cmd, args, inherit,
+                            FALSE, infile, FALSE, outfile, FALSE, errfile,
+                            pool));
 
   return svn_io_wait_for_cmd(&cmd_proc, cmd, exitcode, exitwhy, pool);
 }

Modified: subversion/branches/performance/subversion/libsvn_subr/mergeinfo.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_subr/mergeinfo.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_subr/mergeinfo.c (original)
+++ subversion/branches/performance/subversion/libsvn_subr/mergeinfo.c Wed Dec 29 21:12:33 2010
@@ -668,7 +668,7 @@ parse_revision_line(const char **input, 
      absolute path key. */
   existing_rangelist = apr_hash_get(hash, pathname->data, APR_HASH_KEY_STRING);
   if (existing_rangelist)
-    svn_rangelist_merge(&rangelist, existing_rangelist, pool);
+    SVN_ERR(svn_rangelist_merge(&rangelist, existing_rangelist, pool));
 
   apr_hash_set(hash, pathname->data, APR_HASH_KEY_STRING, rangelist);
 
@@ -1188,9 +1188,9 @@ mergeinfo_hash_diff_cb(const void *key, 
       apr_array_header_t *deleted_rangelist, *added_rangelist;
       from_rangelist = apr_hash_get(cb->from, path, APR_HASH_KEY_STRING);
       to_rangelist = apr_hash_get(cb->to, path, APR_HASH_KEY_STRING);
-      svn_rangelist_diff(&deleted_rangelist, &added_rangelist,
-                         from_rangelist, to_rangelist,
-                         cb->consider_inheritance, cb->pool);
+      SVN_ERR(svn_rangelist_diff(&deleted_rangelist, &added_rangelist,
+                                 from_rangelist, to_rangelist,
+                                 cb->consider_inheritance, cb->pool));
       if (cb->deleted && deleted_rangelist->nelts > 0)
         apr_hash_set(cb->deleted, apr_pstrdup(cb->pool, path),
                      APR_HASH_KEY_STRING, deleted_rangelist);

Modified: subversion/branches/performance/subversion/libsvn_subr/opt.c
URL: http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_subr/opt.c?rev=1053735&r1=1053734&r2=1053735&view=diff
==============================================================================
--- subversion/branches/performance/subversion/libsvn_subr/opt.c (original)
+++ subversion/branches/performance/subversion/libsvn_subr/opt.c Wed Dec 29 21:12:33 2010
@@ -662,7 +662,7 @@ svn_opt_push_implicit_dot_target(apr_arr
                                  apr_pool_t *pool)
 {
   if (targets->nelts == 0)
-    array_push_str(targets, "", pool); /* Ha! "", not ".", is the canonical */
+    APR_ARRAY_PUSH(targets, const char *) = ""; /* Ha! "", not ".", is the canonical */
   assert(targets->nelts);
 }