You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by hw...@apache.org on 2012/05/08 18:43:18 UTC

svn commit: r1335628 [1/2] - in /subversion/branches/ev2-export: ./ build/ subversion/include/ subversion/libsvn_client/ subversion/libsvn_fs/ subversion/libsvn_fs_fs/ subversion/libsvn_ra_serf/ subversion/libsvn_subr/ subversion/tests/cmdline/ subvers...

Author: hwright
Date: Tue May  8 16:43:17 2012
New Revision: 1335628

URL: http://svn.apache.org/viewvc?rev=1335628&view=rev
Log:
On the ev2-export branch:
Out daily sync merge: bring up-to-date with trunk.

Modified:
    subversion/branches/ev2-export/   (props changed)
    subversion/branches/ev2-export/build/run_tests.py
    subversion/branches/ev2-export/subversion/include/svn_io.h
    subversion/branches/ev2-export/subversion/include/svn_ra.h
    subversion/branches/ev2-export/subversion/libsvn_client/locking_commands.c
    subversion/branches/ev2-export/subversion/libsvn_client/update.c
    subversion/branches/ev2-export/subversion/libsvn_fs/editor.c
    subversion/branches/ev2-export/subversion/libsvn_fs_fs/fs.c
    subversion/branches/ev2-export/subversion/libsvn_fs_fs/fs.h
    subversion/branches/ev2-export/subversion/libsvn_fs_fs/fs_fs.c
    subversion/branches/ev2-export/subversion/libsvn_ra_serf/commit.c
    subversion/branches/ev2-export/subversion/libsvn_ra_serf/locks.c
    subversion/branches/ev2-export/subversion/libsvn_ra_serf/ra_serf.h
    subversion/branches/ev2-export/subversion/libsvn_ra_serf/update.c
    subversion/branches/ev2-export/subversion/libsvn_ra_serf/util.c
    subversion/branches/ev2-export/subversion/libsvn_subr/stream.c
    subversion/branches/ev2-export/subversion/tests/cmdline/basic_tests.py
    subversion/branches/ev2-export/subversion/tests/cmdline/lock_tests.py
    subversion/branches/ev2-export/subversion/tests/cmdline/svnadmin_tests.py
    subversion/branches/ev2-export/subversion/tests/cmdline/svntest/main.py
    subversion/branches/ev2-export/win-tests.py

Propchange: subversion/branches/ev2-export/
------------------------------------------------------------------------------
  Merged /subversion/trunk:r1335225-1335623

Modified: subversion/branches/ev2-export/build/run_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/build/run_tests.py?rev=1335628&r1=1335627&r2=1335628&view=diff
==============================================================================
--- subversion/branches/ev2-export/build/run_tests.py (original)
+++ subversion/branches/ev2-export/build/run_tests.py Tue May  8 16:43:17 2012
@@ -453,6 +453,11 @@ class TestHarness:
     if self.milestone_filter is not None:
       svntest.main.options.milestone_filter = self.milestone_filter
     if self.set_log_level is not None:
+      # Somehow the logger is not setup correctly from win-tests.py, so
+      # setting the log level would fail. ### Please fix
+      if svntest.main.logger is None:
+        import logging
+        svntest.main.logger = logging.getLogger()
       svntest.main.logger.setLevel(self.set_log_level)
     if self.svn_bin is not None:
       svntest.main.options.svn_bin = self.svn_bin

Modified: subversion/branches/ev2-export/subversion/include/svn_io.h
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/include/svn_io.h?rev=1335628&r1=1335627&r2=1335628&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/include/svn_io.h (original)
+++ subversion/branches/ev2-export/subversion/include/svn_io.h Tue May  8 16:43:17 2012
@@ -1329,6 +1329,34 @@ svn_string_from_stream(svn_string_t **re
                        apr_pool_t *scratch_pool);
 
 
+/** A function type provided for use as a callback from
+ * @c svn_stream_lazyopen_create().
+ *
+ * @since New in 1.8.
+ */
+typedef svn_error_t *
+(*svn_stream_lazyopen_func_t)(svn_stream_t **stream,
+                              void *baton,
+                              apr_pool_t *result_pool,
+                              apr_pool_t *scratch_pool);
+
+
+/** Set @a *stream to a generic stream which wraps another primary
+ * stream, delaying the "opening" of that stream until the first time
+ * the stream is accessed.
+ *
+ * @a open_func and @a open_baton are a callback function/baton pair
+ * invoked upon the first read of @a *stream which are used to open the
+ * "real" source stream.
+ *
+ * @since New in 1.8.
+ */
+svn_error_t *
+svn_stream_lazyopen_create(svn_stream_t **stream,
+                           svn_stream_lazyopen_func_t open_func,
+                           void *open_baton,
+                           apr_pool_t *result_pool);
+
 /** @} */
 
 /** Set @a *result to a string containing the contents of @a

Modified: subversion/branches/ev2-export/subversion/include/svn_ra.h
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/include/svn_ra.h?rev=1335628&r1=1335627&r2=1335628&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/include/svn_ra.h (original)
+++ subversion/branches/ev2-export/subversion/include/svn_ra.h Tue May  8 16:43:17 2012
@@ -124,11 +124,14 @@ typedef svn_error_t *(*svn_ra_invalidate
  * cached pristine file contents whose SHA1 checksum is @a
  * sha1_checksum, if any.  @a *contents will be a read stream
  * containing those contents if they are found; NULL otherwise.
+ *
+ * @since New in 1.8.
  */
-typedef svn_error_t *(*svn_ra_get_wc_contents_func_t)(void *baton,
-                                                      svn_stream_t **contents,
-                                                      const svn_checksum_t *sha1_checksum,
-                                                      apr_pool_t *pool);
+typedef svn_error_t *
+(*svn_ra_get_wc_contents_func_t)(void *baton,
+                                 svn_stream_t **contents,
+                                 const svn_checksum_t *sha1_checksum,
+                                 apr_pool_t *pool);
 
 
 /** A function type for retrieving the youngest revision from a repos. */

Modified: subversion/branches/ev2-export/subversion/libsvn_client/locking_commands.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_client/locking_commands.c?rev=1335628&r1=1335627&r2=1335628&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_client/locking_commands.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_client/locking_commands.c Tue May  8 16:43:17 2012
@@ -44,7 +44,7 @@
 /* For use with store_locks_callback, below. */
 struct lock_baton
 {
-  const char *base_path;
+  const char *base_dir_abspath;
   apr_hash_t *urls_to_paths;
   svn_client_ctx_t *ctx;
   apr_pool_t *pool;
@@ -55,8 +55,8 @@ struct lock_baton
  * BATON is a 'struct lock_baton *', PATH is the path being locked,
  * and LOCK is the lock itself.
  *
- * If BATON->base_path is not null, then this function either stores
- * the LOCK on REL_URL or removes any lock tokens from REL_URL
+ * If BATON->base_dir_abspath is not null, then this function either
+ * stores the LOCK on REL_URL or removes any lock tokens from REL_URL
  * (depending on whether DO_LOCK is true or false respectively), but
  * only if RA_ERR is null, or (in the unlock case) is something other
  * than SVN_ERR_FS_LOCK_OWNER_MISMATCH.
@@ -86,20 +86,17 @@ store_locks_callback(void *baton,
   notify->lock = lock;
   notify->err = ra_err;
 
-  if (lb->base_path)
+  if (lb->base_dir_abspath)
     {
       char *path = apr_hash_get(lb->urls_to_paths, rel_url,
                                 APR_HASH_KEY_STRING);
       const char *local_abspath;
 
-      SVN_ERR(svn_dirent_get_absolute(&local_abspath,
-                                      svn_dirent_join(lb->base_path,
-                                                      path, pool),
-                                      pool));
+      local_abspath = svn_dirent_join(lb->base_dir_abspath, path, pool);
 
       /* Notify a valid working copy path */
       notify->path = local_abspath;
-      notify->path_prefix = lb->base_path;
+      notify->path_prefix = lb->base_dir_abspath;
 
       if (do_lock)
         {
@@ -457,7 +454,7 @@ svn_client_lock(const apr_array_header_t
                                                NULL, FALSE, FALSE,
                                                ctx, pool));
 
-  cb.base_path = base_dir;
+  cb.base_dir_abspath = base_dir_abspath;
   cb.urls_to_paths = urls_to_paths;
   cb.ctx = ctx;
   cb.pool = pool;
@@ -504,7 +501,7 @@ svn_client_unlock(const apr_array_header
   if (! base_dir && !break_lock)
     SVN_ERR(fetch_tokens(ra_session, path_tokens, pool));
 
-  cb.base_path = base_dir;
+  cb.base_dir_abspath = base_dir_abspath;
   cb.urls_to_paths = urls_to_paths;
   cb.ctx = ctx;
   cb.pool = pool;

Modified: subversion/branches/ev2-export/subversion/libsvn_client/update.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_client/update.c?rev=1335628&r1=1335627&r2=1335628&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_client/update.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_client/update.c Tue May  8 16:43:17 2012
@@ -194,7 +194,7 @@ update_internal(svn_revnum_t *result_rev
   const char *anchor_url;
   const char *corrected_url;
   const char *target;
-  const char *repos_root;
+  const char *repos_root_url;
   const char *repos_relpath;
   svn_error_t *err;
   svn_revnum_t revnum;
@@ -223,7 +223,7 @@ update_internal(svn_revnum_t *result_rev
     target = "";
 
   /* Check if our anchor exists in BASE. If it doesn't we can't update. */
-  SVN_ERR(svn_wc__node_get_base(&revnum, &repos_relpath, &repos_root, NULL,
+  SVN_ERR(svn_wc__node_get_base(&revnum, &repos_relpath, &repos_root_url, NULL,
                                 ctx->wc_ctx, anchor_abspath, pool, pool));
 
   /* It does not make sense to update conflict victims. */
@@ -263,7 +263,8 @@ update_internal(svn_revnum_t *result_rev
                                _("'%s' has no URL"),
                                svn_dirent_local_style(anchor_abspath, pool));
 
-  anchor_url = svn_path_url_add_component2(repos_root, repos_relpath, pool);
+  anchor_url = svn_path_url_add_component2(repos_root_url, repos_relpath,
+                                           pool);
 
   /* We may need to crop the tree if the depth is sticky */
   if (depth_is_sticky && depth < svn_depth_infinity)
@@ -340,18 +341,19 @@ update_internal(svn_revnum_t *result_rev
      relocate our working copy first. */
   if (corrected_url)
     {
-      const char *current_repos_root;
-      const char *current_uuid;
+      const char *new_repos_root_url;
 
       /* To relocate everything inside our repository we need the old and new
-         repos root. ### And we should only perform relocates on the wcroot */
-      SVN_ERR(svn_wc__node_get_repos_info(&current_repos_root, &current_uuid,
-                                          ctx->wc_ctx, anchor_abspath,
-                                          pool, pool));
-
-      /* ### Check uuid here before calling relocate? */
-      SVN_ERR(svn_client_relocate2(anchor_abspath, current_repos_root,
-                                   repos_root, ignore_externals, ctx, pool));
+         repos root. */
+      SVN_ERR(svn_ra_get_repos_root2(ra_session, &new_repos_root_url, pool));
+
+      /* svn_client_relocate2() will check the uuid */
+      SVN_ERR(svn_client_relocate2(anchor_abspath, repos_root_url,
+                                   new_repos_root_url, ignore_externals,
+                                   ctx, pool));
+
+      /* Store updated repository root for externals */
+      repos_root_url = new_repos_root_url;
       anchor_url = corrected_url;
     }
 
@@ -428,7 +430,7 @@ update_internal(svn_revnum_t *result_rev
 
       SVN_ERR(svn_client__handle_externals(new_externals,
                                            new_depths,
-                                           repos_root, local_abspath,
+                                           repos_root_url, local_abspath,
                                            depth, use_sleep,
                                            ctx, pool));
     }

Modified: subversion/branches/ev2-export/subversion/libsvn_fs/editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_fs/editor.c?rev=1335628&r1=1335627&r2=1335628&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_fs/editor.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_fs/editor.c Tue May  8 16:43:17 2012
@@ -216,53 +216,53 @@ can_modify(svn_fs_root_t *txn_root,
                              fspath);
 #endif
 
-      if (revision < created_rev)
+  if (revision < created_rev)
+    {
+      /* We asked to change a node that is *older* than what we found
+         in the transaction. The client is out of date.  */
+      return svn_error_createf(SVN_ERR_FS_OUT_OF_DATE, NULL,
+                               _("'%s' is out of date; try updating"),
+                               fspath);
+    }
+
+  if (revision > created_rev)
+    {
+      /* We asked to change a node that is *newer* than what we found
+         in the transaction. Given that the transaction was based off
+         of 'youngest', then either:
+         - the caller asked to modify a future node
+         - the caller has committed more revisions since this txn
+         was constructed, and is asking to modify a node in one
+         of those new revisions.
+         In either case, the node may not have changed in those new
+         revisions; use the node's ID to determine this case.  */
+      const svn_fs_id_t *txn_noderev_id;
+      svn_fs_root_t *rev_root;
+      const svn_fs_id_t *new_noderev_id;
+
+      /* The ID of the node that we would be modifying in the txn  */
+      SVN_ERR(svn_fs_node_id(&txn_noderev_id, txn_root, fspath,
+                             scratch_pool));
+
+      /* Get the ID from the future/new revision.  */
+      SVN_ERR(svn_fs_revision_root(&rev_root, svn_fs_root_fs(txn_root),
+                                   revision, scratch_pool));
+      SVN_ERR(svn_fs_node_id(&new_noderev_id, rev_root, fspath,
+                             scratch_pool));
+      svn_fs_close_root(rev_root);
+
+      /* Has the target node changed in the future?  */
+      if (svn_fs_compare_ids(txn_noderev_id, new_noderev_id) != 0)
         {
-          /* We asked to change a node that is *older* than what we found
-             in the transaction. The client is out of date.  */
-          return svn_error_createf(SVN_ERR_FS_OUT_OF_DATE, NULL,
-                                   _("'%s' is out of date; try updating"),
+          /* Restarting the commit will base the txn on the future/new
+             revision, allowing the modification at REVISION.  */
+          /* ### use a custom error code  */
+          return svn_error_createf(SVN_ERR_FS_CONFLICT, NULL,
+                                   _("'%s' has been modified since the "
+                                     "commit began (restart the commit)"),
                                    fspath);
         }
-
-    if (revision > created_rev)
-      {
-        /* We asked to change a node that is *newer* than what we found
-           in the transaction. Given that the transaction was based off
-           of 'youngest', then either:
-           - the caller asked to modify a future node
-           - the caller has committed more revisions since this txn
-           was constructed, and is asking to modify a node in one
-           of those new revisions.
-           In either case, the node may not have changed in those new
-           revisions; use the node's ID to determine this case.  */
-        const svn_fs_id_t *txn_noderev_id;
-        svn_fs_root_t *rev_root;
-        const svn_fs_id_t *new_noderev_id;
-
-        /* The ID of the node that we would be modifying in the txn  */
-        SVN_ERR(svn_fs_node_id(&txn_noderev_id, txn_root, fspath,
-                               scratch_pool));
-
-        /* Get the ID from the future/new revision.  */
-        SVN_ERR(svn_fs_revision_root(&rev_root, svn_fs_root_fs(txn_root),
-                                     revision, scratch_pool));
-        SVN_ERR(svn_fs_node_id(&new_noderev_id, rev_root, fspath,
-                               scratch_pool));
-        svn_fs_close_root(rev_root);
-
-        /* Has the target node changed in the future?  */
-        if (svn_fs_compare_ids(txn_noderev_id, new_noderev_id) != 0)
-          {
-            /* Restarting the commit will base the txn on the future/new
-               revision, allowing the modification at REVISION.  */
-            /* ### use a custom error code  */
-            return svn_error_createf(SVN_ERR_FS_CONFLICT, NULL,
-                                     _("'%s' has been modified since the "
-                                       "commit began (restart the commit)"),
-                                     fspath);
-          }
-      }
+    }
 
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/ev2-export/subversion/libsvn_fs_fs/fs.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_fs_fs/fs.c?rev=1335628&r1=1335627&r2=1335628&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_fs_fs/fs.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_fs_fs/fs.c Tue May  8 16:43:17 2012
@@ -294,33 +294,18 @@ fs_hotcopy(svn_fs_t *src_fs,
            void *cancel_baton,
            apr_pool_t *pool)
 {
-    {
-      svn_fs_t *fs = src_fs;
-      const char *path = src_path;
-
-      SVN_ERR(svn_fs__check_fs(fs, FALSE));
-      SVN_ERR(initialize_fs_struct(fs));
-      SVN_ERR(svn_fs_fs__open(fs, path, pool));
-      SVN_ERR(svn_fs_fs__initialize_caches(fs, pool));
-      SVN_ERR(fs_serialized_init(fs, pool, pool));
-    }
-
-    {
-      svn_fs_t *fs = dst_fs;
-
-      SVN_ERR(svn_fs__check_fs(fs, FALSE));
-      SVN_ERR(initialize_fs_struct(fs));
-#if 0 
-      /* In INCREMENTAL mode, svn_fs_fs__hotcopy() will open DST_FS.
-         Otherwise, it's not an FS yet --- possibly just an empty dir --- so
-         can't be opened.
-       */
-      SVN_ERR(svn_fs_fs__open(fs, path, pool));
-      SVN_ERR(svn_fs_fs__initialize_caches(fs, pool));
-#endif
-      SVN_ERR(fs_serialized_init(fs, pool, pool));
-    }
-
+  SVN_ERR(svn_fs__check_fs(src_fs, FALSE));
+  SVN_ERR(initialize_fs_struct(src_fs));
+  SVN_ERR(svn_fs_fs__open(src_fs, src_path, pool));
+  SVN_ERR(svn_fs_fs__initialize_caches(src_fs, pool));
+  SVN_ERR(fs_serialized_init(src_fs, pool, pool));
+
+  SVN_ERR(svn_fs__check_fs(dst_fs, FALSE));
+  SVN_ERR(initialize_fs_struct(dst_fs));
+  /* In INCREMENTAL mode, svn_fs_fs__hotcopy() will open DST_FS.
+     Otherwise, it's not an FS yet --- possibly just an empty dir --- so
+     can't be opened.
+   */
   return svn_fs_fs__hotcopy(src_fs, dst_fs, src_path, dst_path,
                             incremental, cancel_func, cancel_baton, pool);
 }

Modified: subversion/branches/ev2-export/subversion/libsvn_fs_fs/fs.h
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_fs_fs/fs.h?rev=1335628&r1=1335627&r2=1335628&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_fs_fs/fs.h (original)
+++ subversion/branches/ev2-export/subversion/libsvn_fs_fs/fs.h Tue May  8 16:43:17 2012
@@ -61,7 +61,7 @@ extern "C" {
 #define PATH_LOCKS_DIR        "locks"            /* Directory of locks */
 #define PATH_MIN_UNPACKED_REV "min-unpacked-rev" /* Oldest revision which
                                                     has not been packed. */
-#define PATH_REVPROP_GENERATION "revprop-geneneration"
+#define PATH_REVPROP_GENERATION "revprop-generation"
                                                  /* Current revprop generation*/
 /* If you change this, look at tests/svn_test_fs.c(maybe_install_fsfs_conf) */
 #define PATH_CONFIG           "fsfs.conf"        /* Configuration */

Modified: subversion/branches/ev2-export/subversion/libsvn_fs_fs/fs_fs.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_fs_fs/fs_fs.c?rev=1335628&r1=1335627&r2=1335628&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_fs_fs/fs_fs.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_fs_fs/fs_fs.c Tue May  8 16:43:17 2012
@@ -9199,6 +9199,15 @@ hotcopy_body(void *baton, apr_pool_t *po
     SVN_ERR(svn_io_dir_file_copy(src_fs->path, dst_fs->path,
                                  PATH_TXN_CURRENT, pool));
 
+  /* If a revprop generation file exists in the source filesystem,
+   * force a fresh revprop caching namespace for the destination by
+   * setting the generation to zero. We have no idea if the revprops
+   * we copied above really belong to the currently cached generation. */
+  SVN_ERR(svn_io_check_path(path_revprop_generation(src_fs, pool),
+                            &kind, pool));
+  if (kind == svn_node_file)
+    SVN_ERR(write_revprop_generation_file(dst_fs, 0, pool));
+
   /* Hotcopied FS is complete. Stamp it with a format file. */
   SVN_ERR(write_format(svn_dirent_join(dst_fs->path, PATH_FORMAT, pool),
                        dst_ffd->format, max_files_per_dir, TRUE, pool));
@@ -9207,6 +9216,20 @@ hotcopy_body(void *baton, apr_pool_t *po
 }
 
 
+/* Set up shared data between SRC_FS and DST_FS. */
+static void
+hotcopy_setup_shared_fs_data(svn_fs_t *src_fs, svn_fs_t *dst_fs)
+{
+  fs_fs_data_t *src_ffd = src_fs->fsap_data;
+  fs_fs_data_t *dst_ffd = dst_fs->fsap_data;
+
+  /* The common pool and mutexes are shared between src and dst filesystems.
+   * During hotcopy we only grab the mutexes for the destination, so there
+   * is no risk of dead-lock. We don't write to the src filesystem. Shared
+   * data for the src_fs has already been initialised in fs_hotcopy(). */
+  dst_ffd->shared = src_ffd->shared;
+}
+
 /* Create an empty filesystem at DST_FS at DST_PATH with the same
  * configuration as SRC_FS (uuid, format, and other parameters).
  * After creation DST_FS has no revisions, not even revision zero. */
@@ -9282,6 +9305,10 @@ hotcopy_create_empty_dest(svn_fs_t *src_
     }
 
   dst_ffd->youngest_rev_cache = 0;
+
+  hotcopy_setup_shared_fs_data(src_fs, dst_fs);
+  SVN_ERR(svn_fs_fs__initialize_caches(dst_fs, pool));
+
   return SVN_NO_ERROR;
 }
 
@@ -9323,6 +9350,8 @@ svn_fs_fs__hotcopy(svn_fs_t *src_fs,
           SVN_ERR(svn_fs_fs__open(dst_fs, dst_path, pool));
           SVN_ERR(hotcopy_incremental_check_preconditions(src_fs, dst_fs,
                                                           pool));
+          hotcopy_setup_shared_fs_data(src_fs, dst_fs);
+          SVN_ERR(svn_fs_fs__initialize_caches(dst_fs, pool));
         }
     }
   else

Modified: subversion/branches/ev2-export/subversion/libsvn_ra_serf/commit.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra_serf/commit.c?rev=1335628&r1=1335627&r2=1335628&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra_serf/commit.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra_serf/commit.c Tue May  8 16:43:17 2012
@@ -56,7 +56,6 @@ typedef struct checkout_context_t {
      NULL for resources implicitly checked out (ie. an ancestor was
      checked out).  */
   svn_ra_serf__handler_t *handler;
-  svn_ra_serf__simple_request_context_t progress;
   apr_pool_t *result_pool;
   const char *activity_url;
 
@@ -113,7 +112,6 @@ typedef struct proppatch_context_t {
   /* In HTTP v2, this is the file/directory version we think we're changing. */
   svn_revnum_t base_revision;
 
-  svn_ra_serf__simple_request_context_t progress;
 } proppatch_context_t;
 
 typedef struct delete_context_t {
@@ -125,7 +123,6 @@ typedef struct delete_context_t {
   apr_hash_t *lock_token_hash;
   svn_boolean_t keep_locks;
 
-  svn_ra_serf__simple_request_context_t progress;
 } delete_context_t;
 
 /* Represents a directory. */
@@ -222,8 +219,7 @@ typedef struct file_context_t {
 /* Setup routines and handlers for various requests we'll invoke. */
 
 static svn_error_t *
-return_response_err(svn_ra_serf__handler_t *handler,
-                    svn_error_t *server_err)
+return_response_err(svn_ra_serf__handler_t *handler)
 {
   svn_error_t *err;
 
@@ -232,7 +228,9 @@ return_response_err(svn_ra_serf__handler
 
   /* Ye Olde Fallback Error */
   err = svn_error_compose_create(
-            server_err,
+            handler->server_error != NULL
+              ? handler->server_error->error
+              : SVN_NO_ERROR,
             svn_error_createf(SVN_ERR_RA_DAV_REQUEST_FAILED, NULL,
                               _("%s of '%s': %d %s"),
                               handler->method, handler->path,
@@ -290,8 +288,8 @@ handle_checkout(serf_request_t *request,
   checkout_context_t *ctx = baton;
   svn_ra_serf__handler_t *handler = ctx->handler;
 
-  svn_error_t *err = svn_ra_serf__handle_status_only(request, response,
-                                                     &ctx->progress, pool);
+  svn_error_t *err = svn_ra_serf__expect_empty_body(request, response,
+                                                    handler, pool);
 
   /* These handler functions are supposed to return an APR_EOF status
      wrapped in a svn_error_t to indicate to serf that the response was
@@ -301,7 +299,7 @@ handle_checkout(serf_request_t *request,
     return err;
 
   /* Get the resulting location. */
-  if (ctx->progress.done && handler->sline.code == 201)
+  if (handler->done && handler->sline.code == 201)
     {
       serf_bucket_t *hdrs;
       apr_uri_t uri;
@@ -366,7 +364,6 @@ checkout_dir(dir_context_t *dir)
 
   checkout_ctx = apr_pcalloc(dir->pool, sizeof(*checkout_ctx));
   checkout_ctx->handler = handler;
-  checkout_ctx->progress.pool = dir->pool;
   checkout_ctx->result_pool = dir->pool;
   checkout_ctx->activity_url = dir->commit->activity_url;
 
@@ -395,11 +392,7 @@ checkout_dir(dir_context_t *dir)
   handler->method = "CHECKOUT";
   handler->path = checkout_url;
 
-  svn_ra_serf__request_create(handler);
-
-  err = svn_ra_serf__context_run_wait(&checkout_ctx->progress.done,
-                                      dir->commit->session,
-                                      dir->pool);
+  err = svn_ra_serf__context_run_one(handler, dir->pool);
   if (err)
     {
       if (err->apr_err == SVN_ERR_FS_CONFLICT)
@@ -411,9 +404,7 @@ checkout_dir(dir_context_t *dir)
 
   if (handler->sline.code != 201)
     {
-      return svn_error_trace(return_response_err(
-                               handler,
-                               checkout_ctx->progress.server_error.error));
+      return svn_error_trace(return_response_err(handler));
     }
 
   return SVN_NO_ERROR;
@@ -555,7 +546,6 @@ checkout_file(file_context_t *file)
 
   file->checkout = apr_pcalloc(file->pool, sizeof(*file->checkout));
   file->checkout->handler = handler;
-  file->checkout->progress.pool = file->pool;
   file->checkout->result_pool = file->pool;
   file->checkout->activity_url = file->commit->activity_url;
 
@@ -574,14 +564,10 @@ checkout_file(file_context_t *file)
   handler->method = "CHECKOUT";
   handler->path = checkout_url;
 
-  svn_ra_serf__request_create(handler);
-
   /* There's no need to wait here as we only need this when we start the
    * PROPPATCH or PUT of the file.
    */
-  err = svn_ra_serf__context_run_wait(&file->checkout->progress.done,
-                                      file->commit->session,
-                                      file->pool);
+  err = svn_ra_serf__context_run_one(handler, file->pool);
   if (err)
     {
       if (err->apr_err == SVN_ERR_FS_CONFLICT)
@@ -593,9 +579,7 @@ checkout_file(file_context_t *file)
 
   if (handler->sline.code != 201)
     {
-      return svn_error_trace(return_response_err(
-                               handler,
-                               file->checkout->progress.server_error.error));
+      return svn_error_trace(return_response_err(handler));
     }
 
   return SVN_NO_ERROR;
@@ -960,11 +944,7 @@ proppatch_resource(proppatch_context_t *
     {
       return svn_error_create(
                SVN_ERR_RA_DAV_PROPPATCH_FAILED,
-               return_response_err(handler,
-                                   handler->server_error != NULL
-                                     ? handler->server_error->error
-                                     : SVN_NO_ERROR
-                                   ),
+               return_response_err(handler),
                _("At least one property change failed; repository"
                  " is unchanged"));
     }
@@ -1221,7 +1201,7 @@ setup_post_headers(serf_bucket_t *header
 /* Handler baton for POST request. */
 typedef struct post_response_ctx_t
 {
-  svn_ra_serf__simple_request_context_t *request_ctx;
+  svn_ra_serf__handler_t *handler;
   commit_context_t *commit_ctx;
 } post_response_ctx_t;
 
@@ -1266,14 +1246,15 @@ post_headers_iterator_callback(void *bat
 
 
 /* A custom serf_response_handler_t which is mostly a wrapper around
-   svn_ra_serf__handle_status_only -- it just notices POST response
+   svn_ra_serf__expect_empty_body -- it just notices POST response
    headers, too.
+
    Implements svn_ra_serf__response_handler_t */
 static svn_error_t *
 post_response_handler(serf_request_t *request,
                       serf_bucket_t *response,
                       void *baton,
-                      apr_pool_t *pool)
+                      apr_pool_t *scratch_pool)
 {
   post_response_ctx_t *prc = baton;
   serf_bucket_t *hdrs = serf_bucket_response_get_headers(response);
@@ -1282,8 +1263,8 @@ post_response_handler(serf_request_t *re
   serf_bucket_headers_do(hdrs, post_headers_iterator_callback, prc);
 
   /* Execute the 'real' response handler to XML-parse the repsonse body. */
-  return svn_ra_serf__handle_status_only(request, response,
-                                         prc->request_ctx, pool);
+  return svn_ra_serf__expect_empty_body(request, response,
+                                        prc->handler, scratch_pool);
 }
 
 
@@ -1305,7 +1286,6 @@ open_root(void *edit_baton,
 
   if (SVN_RA_SERF__HAVE_HTTPV2_SUPPORT(ctx->session))
     {
-      svn_ra_serf__simple_request_context_t *post_ctx;
       post_response_ctx_t *prc;
       const char *rel_path;
 
@@ -1322,20 +1302,14 @@ open_root(void *edit_baton,
       handler->conn = ctx->session->conns[0];
       handler->session = ctx->session;
 
-      post_ctx = apr_pcalloc(ctx->pool, sizeof(*post_ctx));
-      post_ctx->pool = ctx->pool;
-
       prc = apr_pcalloc(ctx->pool, sizeof(*prc));
-      prc->request_ctx = post_ctx;
+      prc->handler = handler;
       prc->commit_ctx = ctx;
 
       handler->response_handler = post_response_handler;
       handler->response_baton = prc;
 
-      svn_ra_serf__request_create(handler);
-
-      SVN_ERR(svn_ra_serf__context_run_wait(&post_ctx->done, ctx->session,
-                                            ctx->pool));
+      SVN_ERR(svn_ra_serf__context_run_one(handler, ctx->pool));
 
       if (handler->sline.code != 201)
         {
@@ -1388,7 +1362,6 @@ open_root(void *edit_baton,
   else
     {
       svn_ra_serf__options_context_t *opt_ctx;
-      svn_ra_serf__simple_request_context_t *mkact_ctx;
       const char *activity_str;
 
       SVN_ERR(svn_ra_serf__create_options_req(&opt_ctx, ctx->session,
@@ -1418,16 +1391,10 @@ open_root(void *edit_baton,
       handler->conn = ctx->session->conns[0];
       handler->session = ctx->session;
 
-      mkact_ctx = apr_pcalloc(ctx->pool, sizeof(*mkact_ctx));
-      mkact_ctx->pool = ctx->pool;
+      handler->response_handler = svn_ra_serf__expect_empty_body;
+      handler->response_baton = handler;
 
-      handler->response_handler = svn_ra_serf__handle_status_only;
-      handler->response_baton = mkact_ctx;
-
-      svn_ra_serf__request_create(handler);
-
-      SVN_ERR(svn_ra_serf__context_run_wait(&mkact_ctx->done, ctx->session,
-                                            ctx->pool));
+      SVN_ERR(svn_ra_serf__context_run_one(handler, ctx->pool));
 
       if (handler->sline.code != 201)
         {
@@ -1482,7 +1449,6 @@ open_root(void *edit_baton,
   /* PROPPATCH our revprops and pass them along.  */
   proppatch_ctx = apr_pcalloc(ctx->pool, sizeof(*proppatch_ctx));
   proppatch_ctx->pool = dir_pool;
-  proppatch_ctx->progress.pool = dir_pool;
   proppatch_ctx->commit = ctx;
   proppatch_ctx->path = proppatch_target;
   proppatch_ctx->changed_props = apr_hash_make(proppatch_ctx->pool);
@@ -1552,7 +1518,6 @@ delete_entry(const char *path,
 
   /* DELETE our entry */
   delete_ctx = apr_pcalloc(pool, sizeof(*delete_ctx));
-  delete_ctx->progress.pool = pool;
   delete_ctx->path = apr_pstrdup(pool, path);
   delete_ctx->revision = revision;
   delete_ctx->lock_token_hash = dir->commit->lock_tokens;
@@ -1563,8 +1528,8 @@ delete_entry(const char *path,
   handler->session = dir->commit->session;
   handler->conn = dir->commit->conn;
 
-  handler->response_handler = svn_ra_serf__handle_status_only;
-  handler->response_baton = &delete_ctx->progress;
+  handler->response_handler = svn_ra_serf__expect_empty_body;
+  handler->response_baton = handler;
 
   handler->header_delegate = setup_delete_headers;
   handler->header_delegate_baton = delete_ctx;
@@ -1572,10 +1537,7 @@ delete_entry(const char *path,
   handler->method = "DELETE";
   handler->path = delete_target;
 
-  svn_ra_serf__request_create(handler);
-
-  err = svn_ra_serf__context_run_wait(&delete_ctx->progress.done,
-                                      dir->commit->session, pool);
+  err = svn_ra_serf__context_run_one(handler, pool);
 
   if (err &&
       (err->apr_err == SVN_ERR_FS_BAD_LOCK_TOKEN ||
@@ -1593,12 +1555,7 @@ delete_entry(const char *path,
       handler->body_delegate_baton = delete_ctx;
       handler->body_type = "text/xml";
 
-      svn_ra_serf__request_create(handler);
-
-      delete_ctx->progress.done = 0;
-
-      SVN_ERR(svn_ra_serf__context_run_wait(&delete_ctx->progress.done,
-                                            dir->commit->session, pool));
+      SVN_ERR(svn_ra_serf__context_run_one(handler, pool));
     }
   else if (err)
     {
@@ -1608,9 +1565,7 @@ delete_entry(const char *path,
   /* 204 No Content: item successfully deleted */
   if (handler->sline.code != 204)
     {
-      return svn_error_trace(return_response_err(
-                               handler,
-                               delete_ctx->progress.server_error.error));
+      return svn_error_trace(return_response_err(handler));
     }
 
   apr_hash_set(dir->commit->deleted_entries,
@@ -1631,7 +1586,6 @@ add_directory(const char *path,
   dir_context_t *parent = parent_baton;
   dir_context_t *dir;
   svn_ra_serf__handler_t *handler;
-  svn_ra_serf__simple_request_context_t *add_dir_ctx;
   apr_status_t status;
   const char *mkcol_target;
 
@@ -1672,11 +1626,8 @@ add_directory(const char *path,
   handler->conn = dir->commit->conn;
   handler->session = dir->commit->session;
 
-  add_dir_ctx = apr_pcalloc(dir->pool, sizeof(*add_dir_ctx));
-  add_dir_ctx->pool = dir->pool;
-
-  handler->response_handler = svn_ra_serf__handle_status_only;
-  handler->response_baton = add_dir_ctx;
+  handler->response_handler = svn_ra_serf__expect_empty_body;
+  handler->response_baton = handler;
   if (!dir->copy_path)
     {
       handler->method = "MKCOL";
@@ -1710,10 +1661,7 @@ add_directory(const char *path,
       handler->header_delegate_baton = dir;
     }
 
-  svn_ra_serf__request_create(handler);
-
-  SVN_ERR(svn_ra_serf__context_run_wait(&add_dir_ctx->done,
-                                        dir->commit->session, dir->pool));
+  SVN_ERR(svn_ra_serf__context_run_one(handler, dir->pool));
 
   switch (handler->sline.code)
     {
@@ -1722,12 +1670,14 @@ add_directory(const char *path,
         break;
 
       case 403:
-        SVN_ERR(add_dir_ctx->server_error.error);
+        if (handler->server_error)
+          SVN_ERR(handler->server_error->error);
         return svn_error_createf(SVN_ERR_RA_DAV_FORBIDDEN, NULL,
                                 _("Access to '%s' forbidden"),
                                  handler->path);
       default:
-        SVN_ERR(add_dir_ctx->server_error.error);
+        if (handler->server_error)
+          SVN_ERR(handler->server_error->error);
         return svn_error_createf(SVN_ERR_RA_DAV_REQUEST_FAILED, NULL,
                                  _("Adding directory failed: %s on %s "
                                    "(%d %s)"),
@@ -1849,7 +1799,6 @@ close_directory(void *dir_baton,
 
       proppatch_ctx = apr_pcalloc(pool, sizeof(*proppatch_ctx));
       proppatch_ctx->pool = pool;
-      proppatch_ctx->progress.pool = pool;
       proppatch_ctx->commit = dir->commit;
       proppatch_ctx->relpath = dir->relpath;
       proppatch_ctx->changed_props = dir->changed_props;
@@ -1930,12 +1879,8 @@ add_file(const char *path,
   if (! ((dir->added && !dir->copy_path) ||
          (deleted_parent && deleted_parent[0] != '\0')))
     {
-      svn_ra_serf__simple_request_context_t *head_ctx;
       svn_ra_serf__handler_t *handler;
 
-      head_ctx = apr_pcalloc(new_file->pool, sizeof(*head_ctx));
-      head_ctx->pool = new_file->pool;
-
       handler = apr_pcalloc(new_file->pool, sizeof(*handler));
       handler->handler_pool = new_file->pool;
       handler->session = new_file->commit->session;
@@ -1944,13 +1889,10 @@ add_file(const char *path,
       handler->path = svn_path_url_add_component2(
         dir->commit->session->session_url.path,
         path, new_file->pool);
-      handler->response_handler = svn_ra_serf__handle_status_only;
-      handler->response_baton = head_ctx;
-      svn_ra_serf__request_create(handler);
-
-      SVN_ERR(svn_ra_serf__context_run_wait(&head_ctx->done,
-                                            new_file->commit->session,
-                                            new_file->pool));
+      handler->response_handler = svn_ra_serf__expect_empty_body;
+      handler->response_baton = handler;
+
+      SVN_ERR(svn_ra_serf__context_run_one(handler, new_file->pool));
 
       if (handler->sline.code != 404)
         {
@@ -2095,7 +2037,6 @@ close_file(void *file_baton,
   if (ctx->copy_path)
     {
       svn_ra_serf__handler_t *handler;
-      svn_ra_serf__simple_request_context_t *copy_ctx;
       apr_uri_t uri;
       const char *rel_copy_path, *basecoll_url, *req_url;
 
@@ -2121,25 +2062,17 @@ close_file(void *file_baton,
       handler->conn = ctx->commit->conn;
       handler->session = ctx->commit->session;
 
-      copy_ctx = apr_pcalloc(pool, sizeof(*copy_ctx));
-      copy_ctx->pool = pool;
-
-      handler->response_handler = svn_ra_serf__handle_status_only;
-      handler->response_baton = copy_ctx;
+      handler->response_handler = svn_ra_serf__expect_empty_body;
+      handler->response_baton = handler;
 
       handler->header_delegate = setup_copy_file_headers;
       handler->header_delegate_baton = ctx;
 
-      svn_ra_serf__request_create(handler);
-
-      SVN_ERR(svn_ra_serf__context_run_wait(&copy_ctx->done,
-                                            ctx->commit->session, pool));
+      SVN_ERR(svn_ra_serf__context_run_one(handler, pool));
 
       if (handler->sline.code != 201 && handler->sline.code != 204)
         {
-          return svn_error_trace(return_response_err(
-                                   handler,
-                                   copy_ctx->server_error.error));
+          return svn_error_trace(return_response_err(handler));
         }
     }
 
@@ -2153,7 +2086,6 @@ close_file(void *file_baton,
   if (ctx->stream || put_empty_file)
     {
       svn_ra_serf__handler_t *handler;
-      svn_ra_serf__simple_request_context_t *put_ctx;
 
       handler = apr_pcalloc(pool, sizeof(*handler));
       handler->handler_pool = pool;
@@ -2162,11 +2094,8 @@ close_file(void *file_baton,
       handler->conn = ctx->commit->conn;
       handler->session = ctx->commit->session;
 
-      put_ctx = apr_pcalloc(pool, sizeof(*put_ctx));
-      put_ctx->pool = pool;
-
-      handler->response_handler = svn_ra_serf__handle_status_only;
-      handler->response_baton = put_ctx;
+      handler->response_handler = svn_ra_serf__expect_empty_body;
+      handler->response_baton = handler;
 
       if (put_empty_file)
         {
@@ -2184,16 +2113,11 @@ close_file(void *file_baton,
       handler->header_delegate = setup_put_headers;
       handler->header_delegate_baton = ctx;
 
-      svn_ra_serf__request_create(handler);
-
-      SVN_ERR(svn_ra_serf__context_run_wait(&put_ctx->done,
-                                            ctx->commit->session, pool));
+      SVN_ERR(svn_ra_serf__context_run_one(handler, pool));
 
       if (handler->sline.code != 204 && handler->sline.code != 201)
         {
-          return svn_error_trace(return_response_err(
-                                   handler,
-                                   put_ctx->server_error.error));
+          return svn_error_trace(return_response_err(handler));
         }
     }
 
@@ -2208,7 +2132,6 @@ close_file(void *file_baton,
 
       proppatch = apr_pcalloc(ctx->pool, sizeof(*proppatch));
       proppatch->pool = ctx->pool;
-      proppatch->progress.pool = pool;
       proppatch->relpath = ctx->relpath;
       proppatch->path = ctx->url;
       proppatch->commit = ctx->commit;
@@ -2228,7 +2151,6 @@ close_edit(void *edit_baton,
 {
   commit_context_t *ctx = edit_baton;
   svn_ra_serf__merge_context_t *merge_ctx;
-  svn_ra_serf__simple_request_context_t *delete_ctx;
   svn_ra_serf__handler_t *handler;
   svn_boolean_t *merge_done;
   const char *merge_target =
@@ -2269,16 +2191,10 @@ close_edit(void *edit_baton,
       handler->conn = ctx->conn;
       handler->session = ctx->session;
 
-      delete_ctx = apr_pcalloc(pool, sizeof(*delete_ctx));
-      delete_ctx->pool = pool;
-
-      handler->response_handler = svn_ra_serf__handle_status_only;
-      handler->response_baton = delete_ctx;
+      handler->response_handler = svn_ra_serf__expect_empty_body;
+      handler->response_baton = handler;
 
-      svn_ra_serf__request_create(handler);
-
-      SVN_ERR(svn_ra_serf__context_run_wait(&delete_ctx->done, ctx->session,
-                                            pool));
+      SVN_ERR(svn_ra_serf__context_run_one(handler, pool));
 
       SVN_ERR_ASSERT(handler->sline.code == 204);
     }
@@ -2292,7 +2208,6 @@ abort_edit(void *edit_baton,
 {
   commit_context_t *ctx = edit_baton;
   svn_ra_serf__handler_t *handler;
-  svn_ra_serf__simple_request_context_t *delete_ctx;
 
   /* If an activity or transaction wasn't even created, don't bother
      trying to delete it. */
@@ -2310,21 +2225,15 @@ abort_edit(void *edit_baton,
   handler->conn = ctx->session->conns[0];
   handler->session = ctx->session;
 
-  delete_ctx = apr_pcalloc(pool, sizeof(*delete_ctx));
-  delete_ctx->pool = pool;
-
-  handler->response_handler = svn_ra_serf__handle_status_only;
-  handler->response_baton = delete_ctx;
+  handler->response_handler = svn_ra_serf__expect_empty_body;
+  handler->response_baton = handler;
 
   if (USING_HTTPV2_COMMIT_SUPPORT(ctx)) /* HTTP v2 */
     handler->path = ctx->txn_url;
   else
     handler->path = ctx->activity_url;
 
-  svn_ra_serf__request_create(handler);
-
-  SVN_ERR(svn_ra_serf__context_run_wait(&delete_ctx->done, ctx->session,
-                                        pool));
+  SVN_ERR(svn_ra_serf__context_run_one(handler, pool));
 
   /* 204 if deleted,
      403 if DELETE was forbidden (indicates MKACTIVITY was forbidden too),
@@ -2483,7 +2392,6 @@ svn_ra_serf__change_rev_prop(svn_ra_sess
   /* PROPPATCH our log message and pass it along.  */
   proppatch_ctx = apr_pcalloc(pool, sizeof(*proppatch_ctx));
   proppatch_ctx->pool = pool;
-  proppatch_ctx->progress.pool = pool;
   proppatch_ctx->commit = commit;
   proppatch_ctx->path = proppatch_target;
   proppatch_ctx->changed_props = apr_hash_make(proppatch_ctx->pool);

Modified: subversion/branches/ev2-export/subversion/libsvn_ra_serf/locks.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra_serf/locks.c?rev=1335628&r1=1335627&r2=1335628&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra_serf/locks.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra_serf/locks.c Tue May  8 16:43:17 2012
@@ -72,8 +72,6 @@ typedef struct lock_info_t {
 
   svn_ra_serf__handler_t *handler;
 
-  /* are we done? */
-  svn_boolean_t done;
 } lock_info_t;
 
 
@@ -331,6 +329,42 @@ set_lock_headers(serf_bucket_t *headers,
   return APR_SUCCESS;
 }
 
+
+/* Register an error within the session. If something is already there,
+   then it will take precedence.  */
+static svn_error_t *
+determine_error(svn_ra_serf__handler_t *handler,
+                svn_error_t *err)
+{
+  /* If we found an error in the response, then blend it in.  */
+  if (handler->server_error)
+    {
+      /* Client-side error takes precedence.  */
+      err = svn_error_compose_create(err, handler->server_error->error);
+    }
+  else
+    {
+      apr_status_t errcode;
+
+      if (handler->sline.code == 423)
+        errcode = SVN_ERR_FS_PATH_ALREADY_LOCKED;
+      else if (handler->sline.code == 403)
+        errcode = SVN_ERR_RA_DAV_FORBIDDEN;
+      else
+        return err;
+
+      /* The server did not send us a detailed human-readable error.
+         Provide a generic error.  */
+      err = svn_error_createf(errcode, err,
+                              _("Lock request failed: %d %s"),
+                              handler->sline.code,
+                              handler->sline.reason);
+    }
+
+  return err;
+}
+
+
 /* Implements svn_ra_serf__response_handler_t */
 static svn_error_t *
 handle_lock(serf_request_t *request,
@@ -340,30 +374,24 @@ handle_lock(serf_request_t *request,
 {
   svn_ra_serf__xml_parser_t *xml_ctx = handler_baton;
   lock_info_t *ctx = xml_ctx->user_data;
-  svn_error_t *err;
+
+  /* 403 (Forbidden) when a lock doesn't exist.
+     423 (Locked) when a lock already exists.  */
+  if (ctx->handler->sline.code == 403
+      || ctx->handler->sline.code == 423)
+    {
+      /* Go look in the body for a server-provided error. This will
+         reset flags for the core handler to Do The Right Thing. We
+         won't be back to this handler again.  */
+      return svn_error_trace(svn_ra_serf__expect_empty_body(
+                               request, response, ctx->handler, pool));
+    }
 
   if (ctx->read_headers == FALSE)
     {
       serf_bucket_t *headers;
       const char *val;
 
-      /* 423 == Locked */
-      if (ctx->handler->sline.code == 423)
-        {
-          /* Older servers may not give a descriptive error, so we'll
-             make one of our own if we can't find one in the response. */
-          err = svn_ra_serf__handle_server_error(request, response, pool);
-          if (!err)
-            {
-              err = svn_error_createf(SVN_ERR_FS_PATH_ALREADY_LOCKED,
-                                      NULL,
-                                      _("Lock request failed: %d %s"),
-                                      ctx->handler->sline.code,
-                                      ctx->handler->sline.reason);
-            }
-          return err;
-        }
-
       headers = serf_bucket_response_get_headers(response);
 
       val = serf_bucket_headers_get(headers, SVN_DAV_LOCK_OWNER_HEADER);
@@ -382,24 +410,6 @@ handle_lock(serf_request_t *request,
       ctx->read_headers = TRUE;
     }
 
-  /* Forbidden when a lock doesn't exist. */
-  if (ctx->handler->sline.code == 403)
-    {
-      /* If we get an "unexpected EOF" error, we'll wrap it with
-         generic request failure error. */
-      err = svn_ra_serf__handle_discard_body(request, response, NULL, pool);
-      if (err && APR_STATUS_IS_EOF(err->apr_err))
-        {
-          ctx->done = TRUE;
-          err = svn_error_createf(SVN_ERR_RA_DAV_FORBIDDEN,
-                                  err,
-                                  _("Lock request failed: %d %s"),
-                                  ctx->handler->sline.code,
-                                  ctx->handler->sline.reason);
-        }
-      return err;
-    }
-
   return svn_ra_serf__handle_xml_parser(request, response,
                                         handler_baton, pool);
 }
@@ -513,7 +523,7 @@ svn_ra_serf__get_lock(svn_ra_session_t *
   parser_ctx->start = start_lock;
   parser_ctx->end = end_lock;
   parser_ctx->cdata = cdata_lock;
-  parser_ctx->done = &lock_ctx->done;
+  parser_ctx->done = &handler->done;
 
   handler->body_delegate = create_getlock_body;
   handler->body_delegate_baton = lock_ctx;
@@ -526,8 +536,8 @@ svn_ra_serf__get_lock(svn_ra_session_t *
 
   lock_ctx->handler = handler;
 
-  svn_ra_serf__request_create(handler);
-  err = svn_ra_serf__context_run_wait(&lock_ctx->done, session, pool);
+  err = svn_ra_serf__context_run_one(handler, pool);
+  err = determine_error(handler, err);
 
   if (handler->sline.code == 404)
     {
@@ -608,7 +618,7 @@ svn_ra_serf__lock(svn_ra_session_t *ra_s
       parser_ctx->start = start_lock;
       parser_ctx->end = end_lock;
       parser_ctx->cdata = cdata_lock;
-      parser_ctx->done = &lock_ctx->done;
+      parser_ctx->done = &handler->done;
 
       handler->header_delegate = set_lock_headers;
       handler->header_delegate_baton = lock_ctx;
@@ -621,8 +631,8 @@ svn_ra_serf__lock(svn_ra_session_t *ra_s
 
       lock_ctx->handler = handler;
 
-      svn_ra_serf__request_create(handler);
-      err = svn_ra_serf__context_run_wait(&lock_ctx->done, session, iterpool);
+      err = svn_ra_serf__context_run_one(handler, iterpool);
+      err = determine_error(handler, err);
 
       if (lock_func)
         new_err = lock_func(lock_baton, lock_ctx->path, TRUE, lock_ctx->lock,
@@ -674,13 +684,15 @@ svn_ra_serf__unlock(svn_ra_session_t *ra
   iterpool = svn_pool_create(scratch_pool);
 
   /* ### TODO for issue 2263: Send all the locks over the wire at once.  This
-     loop is just a temporary shim. */
+     ### loop is just a temporary shim.
+     ### an alternative, which is backwards-compat with all servers is to
+     ### pipeline these requests. ie. stop using run_wait/run_one.  */
+
   for (hi = apr_hash_first(scratch_pool, path_tokens);
        hi;
        hi = apr_hash_next(hi))
     {
       svn_ra_serf__handler_t *handler;
-      svn_ra_serf__simple_request_context_t *ctx;
       const char *req_url, *path, *token;
       svn_lock_t *existing_lock = NULL;
       struct unlock_context_t unlock_ctx;
@@ -690,9 +702,6 @@ svn_ra_serf__unlock(svn_ra_session_t *ra
 
       svn_pool_clear(iterpool);
 
-      ctx = apr_pcalloc(iterpool, sizeof(*ctx));
-      ctx->pool = iterpool;
-
       path = svn__apr_hash_index_key(hi);
       token = svn__apr_hash_index_val(hi);
 
@@ -743,11 +752,10 @@ svn_ra_serf__unlock(svn_ra_session_t *ra
       handler->header_delegate = set_unlock_headers;
       handler->header_delegate_baton = &unlock_ctx;
 
-      handler->response_handler = svn_ra_serf__handle_status_only;
-      handler->response_baton = ctx;
+      handler->response_handler = svn_ra_serf__expect_empty_body;
+      handler->response_baton = handler;
 
-      svn_ra_serf__request_create(handler);
-      SVN_ERR(svn_ra_serf__context_run_wait(&ctx->done, session, iterpool));
+      SVN_ERR(svn_ra_serf__context_run_one(handler, iterpool));
 
       switch (handler->sline.code)
         {

Modified: subversion/branches/ev2-export/subversion/libsvn_ra_serf/ra_serf.h
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra_serf/ra_serf.h?rev=1335628&r1=1335627&r2=1335628&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra_serf/ra_serf.h (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra_serf/ra_serf.h Tue May  8 16:43:17 2012
@@ -456,6 +456,11 @@ typedef struct svn_ra_serf__handler_t {
   /* Internal flag to indicate we've parsed the headers.  */
   svn_boolean_t reading_body;
 
+  /* When this flag will be set, the core handler will discard any unread
+     portion of the response body. The registered response handler will
+     no longer be called.  */
+  svn_boolean_t discard_body;
+
   /* Pool for allocating SLINE.REASON and LOCATION. If this pool is NULL,
      then the requestor does not care about SLINE and LOCATION.  */
   apr_pool_t *handler_pool;
@@ -659,29 +664,6 @@ struct svn_ra_serf__server_error_t {
   svn_ra_serf__xml_parser_t parser;
 };
 
-/* A simple request context that can be passed to handle_status_only. */
-typedef struct svn_ra_serf__simple_request_context_t {
-  apr_pool_t *pool;
-
-  /* This value is set to TRUE when the response is completed. */
-  svn_boolean_t done;
-
-  /* If an error occurred, this value will be initialized. */
-  svn_ra_serf__server_error_t server_error;
-} svn_ra_serf__simple_request_context_t;
-
-/*
- * Serf handler for @a request / @a response pair that takes in a
- * @a baton (@see svn_ra_serf__simple_request_context_t).
- * Implements svn_ra_serf__response_handler_t.
- *
- * Temporary allocations are made in @a pool.
- */
-svn_error_t *
-svn_ra_serf__handle_status_only(serf_request_t *request,
-                                serf_bucket_t *response,
-                                void *baton,
-                                apr_pool_t *pool);
 
 /*
  * Handler that discards the entire @a response body associated with a
@@ -698,16 +680,6 @@ svn_ra_serf__handle_discard_body(serf_re
                                  void *baton,
                                  apr_pool_t *pool);
 
-/*
- * Handler that retrieves the embedded XML error response from the
- * the @a response body associated with a @a request.
- *
- * All temporary allocations will be made in a @a pool.
- */
-svn_error_t *
-svn_ra_serf__handle_server_error(serf_request_t *request,
-                                 serf_bucket_t *response,
-                                 apr_pool_t *pool);
 
 /*
  * Handler that retrieves the embedded XML multistatus response from the
@@ -726,6 +698,28 @@ svn_ra_serf__handle_multistatus_only(ser
                                      void *baton,
                                      apr_pool_t *scratch_pool);
 
+
+/* Handler that expects an empty body.
+
+   If a body IS present, and it is text/xml, then it will be parsed for
+   a server-side error.
+
+   BATON should be the svn_ra_serf__handler_t running REQUEST.
+
+   Status line information will be in HANDLER->SLINE.
+
+   Any parsed errors will be left in HANDLER->SERVER_ERROR. That member
+   may be NULL if no body was present, or a problem occurred trying to
+   parse the body.
+
+   All temporary allocations will be made in SCRATCH_POOL.  */
+svn_error_t *
+svn_ra_serf__expect_empty_body(serf_request_t *request,
+                               serf_bucket_t *response,
+                               void *baton,
+                               apr_pool_t *scratch_pool);
+
+
 /*
  * This function will feed the RESPONSE body into XMLP.  When parsing is
  * completed (i.e. an EOF is received), *DONE is set to TRUE.

Modified: subversion/branches/ev2-export/subversion/libsvn_ra_serf/update.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra_serf/update.c?rev=1335628&r1=1335627&r2=1335628&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra_serf/update.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra_serf/update.c Tue May  8 16:43:17 2012
@@ -256,6 +256,9 @@ typedef struct report_info_t
  */
 typedef struct report_fetch_t {
 
+  /* The handler representing this particular fetch.  */
+  svn_ra_serf__handler_t *handler;
+
   /* The session we should use to fetch the file. */
   svn_ra_serf__session_t *sess;
 
@@ -805,6 +808,105 @@ error_fetch(serf_request_t *request,
   return err;
 }
 
+/* Wield the editor referenced by INFO to open (or add) the file
+   file also associated with INFO, setting properties on the file and
+   calling the editor's apply_textdelta() function on it if necessary
+   (or if FORCE_APPLY_TEXTDELTA is set).
+
+   Callers will probably want to also see the function that serves
+   the opposite purpose of this one, close_updated_file().  */
+static svn_error_t *
+open_updated_file(report_info_t *info,
+                  svn_boolean_t force_apply_textdelta,
+                  apr_pool_t *scratch_pool)
+{
+  const svn_delta_editor_t *update_editor = info->dir->update_editor;
+
+  /* Ensure our parent is open. */
+  SVN_ERR(open_dir(info->dir));
+  info->editor_pool = svn_pool_create(info->dir->dir_baton_pool);
+
+  /* Expand our full name now if we haven't done so yet. */
+  if (!info->name)
+    {
+      info->name = svn_relpath_join(info->dir->name, info->base_name,
+                                    info->editor_pool);
+    }
+
+  /* Open (or add) the file. */
+  if (SVN_IS_VALID_REVNUM(info->base_rev))
+    {
+      SVN_ERR(update_editor->open_file(info->name,
+                                       info->dir->dir_baton,
+                                       info->base_rev,
+                                       info->editor_pool,
+                                       &info->file_baton));
+    }
+  else
+    {
+      SVN_ERR(update_editor->add_file(info->name,
+                                      info->dir->dir_baton,
+                                      info->copyfrom_path,
+                                      info->copyfrom_rev,
+                                      info->editor_pool,
+                                      &info->file_baton));
+    }
+
+  /* Check for lock information. */
+  if (info->lock_token)
+    check_lock(info);
+
+  /* Set all of the properties we received */
+  SVN_ERR(svn_ra_serf__walk_all_props(info->props,
+                                      info->base_name,
+                                      info->base_rev,
+                                      set_file_props, info,
+                                      scratch_pool));
+  SVN_ERR(svn_ra_serf__walk_all_props(info->dir->removed_props,
+                                      info->base_name,
+                                      info->base_rev,
+                                      remove_file_props, info,
+                                      scratch_pool));
+  if (info->fetch_props)
+    {
+      SVN_ERR(svn_ra_serf__walk_all_props(info->props,
+                                          info->url,
+                                          info->target_rev,
+                                          set_file_props, info,
+                                          scratch_pool));
+    }
+
+  /* Get (maybe) a textdelta window handler for transmitting file
+     content changes. */
+  if (info->fetch_file || force_apply_textdelta)
+    {
+      SVN_ERR(update_editor->apply_textdelta(info->file_baton,
+                                             info->base_checksum,
+                                             info->editor_pool,
+                                             &info->textdelta,
+                                             &info->textdelta_baton));
+    }
+
+  return SVN_NO_ERROR;
+}
+
+/* Close the file associated with INFO->file_baton, and cleanup other
+   bits of that structure managed by open_updated_file(). */
+static svn_error_t *
+close_updated_file(report_info_t *info,
+                   apr_pool_t *scratch_pool)
+{
+  /* Close the file via the editor. */
+  SVN_ERR(info->dir->update_editor->close_file(info->file_baton,
+                                               info->final_checksum,
+                                               scratch_pool));
+
+  /* We're done with our editor pool. */
+  svn_pool_destroy(info->editor_pool);
+
+  return SVN_NO_ERROR;
+}
+
 /* Implements svn_ra_serf__response_handler_t */
 static svn_error_t *
 handle_fetch(serf_request_t *request,
@@ -817,7 +919,9 @@ handle_fetch(serf_request_t *request,
   apr_status_t status;
   report_fetch_t *fetch_ctx = handler_baton;
   svn_error_t *err;
-  serf_status_line sl;
+
+  /* ### new field. make sure we didn't miss some initialization.  */
+  SVN_ERR_ASSERT(fetch_ctx->handler != NULL);
 
   if (fetch_ctx->read_headers == FALSE)
     {
@@ -829,50 +933,8 @@ handle_fetch(serf_request_t *request,
       val = serf_bucket_headers_get(hdrs, "Content-Type");
       info = fetch_ctx->info;
 
-      err = open_dir(info->dir);
-      if (err)
-        {
-          return error_fetch(request, fetch_ctx, err);
-        }
-
-      info->editor_pool = svn_pool_create(info->dir->dir_baton_pool);
-
-      /* Expand our full name now if we haven't done so yet. */
-      if (!info->name)
-        {
-          info->name = svn_relpath_join(info->dir->name, info->base_name,
-                                        info->editor_pool);
-        }
-
-      if (SVN_IS_VALID_REVNUM(info->base_rev))
-        {
-          err = info->dir->update_editor->open_file(info->name,
-                                                    info->dir->dir_baton,
-                                                    info->base_rev,
-                                                    info->editor_pool,
-                                                    &info->file_baton);
-        }
-      else
-        {
-          err = info->dir->update_editor->add_file(info->name,
-                                                   info->dir->dir_baton,
-                                                   info->copyfrom_path,
-                                                   info->copyfrom_rev,
-                                                   info->editor_pool,
-                                                   &info->file_baton);
-        }
-
-      if (err)
-        {
-          return error_fetch(request, fetch_ctx, err);
-        }
-
-      err = info->dir->update_editor->apply_textdelta(info->file_baton,
-                                                      info->base_checksum,
-                                                      info->editor_pool,
-                                                      &info->textdelta,
-                                                      &info->textdelta_baton);
-
+      /* Open the file for editing. */
+      err = open_updated_file(info, FALSE, info->pool);
       if (err)
         {
           return error_fetch(request, fetch_ctx, err);
@@ -895,16 +957,12 @@ handle_fetch(serf_request_t *request,
 
   /* If the error code wasn't 200, something went wrong. Don't use the returned
      data as its probably an error message. Just bail out instead. */
-  status = serf_bucket_response_status(response, &sl);
-  if (SERF_BUCKET_READ_ERROR(status))
-    {
-      return svn_error_wrap_apr(status, NULL);
-    }
-  if (sl.code != 200)
+  if (fetch_ctx->handler->sline.code != 200)
     {
       err = svn_error_createf(SVN_ERR_RA_DAV_REQUEST_FAILED, NULL,
                               _("GET request failed: %d %s"),
-                              sl.code, sl.reason);
+                              fetch_ctx->handler->sline.code,
+                              fetch_ctx->handler->sline.reason);
       return error_fetch(request, fetch_ctx, err);
     }
 
@@ -987,51 +1045,17 @@ handle_fetch(serf_request_t *request,
         {
           report_info_t *info = fetch_ctx->info;
 
-          /* ### this doesn't feel quite right. but it gets tossed at the
-             ### end of this block, so it will work for now.  */
-          apr_pool_t *scratch_pool = info->editor_pool;
-
           if (fetch_ctx->delta_stream)
             err = svn_error_trace(svn_stream_close(fetch_ctx->delta_stream));
           else
             err = svn_error_trace(info->textdelta(NULL,
                                                   info->textdelta_baton));
-
           if (err)
             {
               return error_fetch(request, fetch_ctx, err);
             }
 
-          if (info->lock_token)
-            check_lock(info);
-
-          /* set all of the properties we received */
-          err = svn_ra_serf__walk_all_props(info->props,
-                                            info->base_name,
-                                            info->base_rev,
-                                            set_file_props, info,
-                                            scratch_pool);
-
-          if (!err)
-            err = svn_ra_serf__walk_all_props(info->dir->removed_props,
-                                              info->base_name,
-                                              info->base_rev,
-                                              remove_file_props, info,
-                                              scratch_pool);
-          if (!err && info->fetch_props)
-            {
-              err = svn_ra_serf__walk_all_props(info->props,
-                                                info->url,
-                                                info->target_rev,
-                                                set_file_props, info,
-                                                scratch_pool);
-            }
-
-          if (!err)
-            err = info->dir->update_editor->close_file(info->file_baton,
-                                                       info->final_checksum,
-                                                       scratch_pool);
-
+          err = close_updated_file(info, info->pool);
           if (err)
             {
               return svn_error_trace(error_fetch(request, fetch_ctx, err));
@@ -1043,8 +1067,7 @@ handle_fetch(serf_request_t *request,
           fetch_ctx->done_item.next = *fetch_ctx->done_list;
           *fetch_ctx->done_list = &fetch_ctx->done_item;
 
-          /* We're done with our pools. */
-          svn_pool_destroy(info->editor_pool);
+          /* We're done with our pool. */
           svn_pool_destroy(info->pool);
 
           if (status)
@@ -1066,26 +1089,22 @@ handle_stream(serf_request_t *request,
               apr_pool_t *pool)
 {
   report_fetch_t *fetch_ctx = handler_baton;
-  serf_status_line sl;
   const char *location;
   svn_error_t *err;
   apr_status_t status;
 
-  status = serf_bucket_response_status(response, &sl);
-  if (SERF_BUCKET_READ_ERROR(status))
-    {
-      return svn_error_wrap_apr(status, NULL);
-    }
+  /* ### new field. make sure we didn't miss some initialization.  */
+  SVN_ERR_ASSERT(fetch_ctx->handler != NULL);
 
   /* Woo-hoo.  Nothing here to see.  */
   location = svn_ra_serf__response_get_location(response, pool);
 
-  err = svn_ra_serf__error_on_status(sl.code,
+  err = svn_ra_serf__error_on_status(fetch_ctx->handler->sline.code,
                                      fetch_ctx->info->name,
                                      location);
   if (err)
     {
-      fetch_ctx->done = TRUE;
+      fetch_ctx->handler->done = TRUE;
 
       err = svn_error_compose_create(
                   err,
@@ -1161,71 +1180,13 @@ static svn_error_t *
 handle_propchange_only(report_info_t *info,
                        apr_pool_t *scratch_pool)
 {
-  /* Ensure our parent is open. */
-  SVN_ERR(open_dir(info->dir));
-
-  info->editor_pool = svn_pool_create(info->dir->dir_baton_pool);
-
-  /* Expand our full name now if we haven't done so yet. */
-  if (!info->name)
-    {
-      info->name = svn_relpath_join(info->dir->name, info->base_name,
-                                    info->editor_pool);
-    }
-
-  if (SVN_IS_VALID_REVNUM(info->base_rev))
-    {
-      SVN_ERR(info->dir->update_editor->open_file(info->name,
-                                                  info->dir->dir_baton,
-                                                  info->base_rev,
-                                                  info->editor_pool,
-                                                  &info->file_baton));
-    }
-  else
-    {
-      SVN_ERR(info->dir->update_editor->add_file(info->name,
-                                                 info->dir->dir_baton,
-                                                 info->copyfrom_path,
-                                                 info->copyfrom_rev,
-                                                 info->editor_pool,
-                                                 &info->file_baton));
-    }
-
-  if (info->fetch_file)
-    {
-      SVN_ERR(info->dir->update_editor->apply_textdelta(info->file_baton,
-                                                    info->base_checksum,
-                                                    info->editor_pool,
-                                                    &info->textdelta,
-                                                    &info->textdelta_baton));
-    }
-
-  if (info->lock_token)
-    check_lock(info);
-
-  /* set all of the properties we received */
-  SVN_ERR(svn_ra_serf__walk_all_props(info->props,
-                                      info->base_name, info->base_rev,
-                                      set_file_props, info,
-                                      scratch_pool));
-  SVN_ERR(svn_ra_serf__walk_all_props(info->dir->removed_props,
-                                      info->base_name, info->base_rev,
-                                      remove_file_props, info,
-                                      scratch_pool));
-  if (info->fetch_props)
-    {
-      SVN_ERR(svn_ra_serf__walk_all_props(info->props, info->url,
-                                          info->target_rev,
-                                          set_file_props, info,
-                                          scratch_pool));
-    }
-
-  SVN_ERR(info->dir->update_editor->close_file(info->file_baton,
-                                               info->final_checksum,
-                                               scratch_pool));
-
-  /* We're done with our pools. */
-  svn_pool_destroy(info->editor_pool);
+  /* Open the file for editing (without forcing an apply_textdelta),
+     pass along any propchanges we've recorded for it, and then close
+     the file. */
+  SVN_ERR(open_updated_file(info, FALSE, scratch_pool));
+  SVN_ERR(close_updated_file(info, scratch_pool));
+  
+  /* We're done with our pool. */
   svn_pool_destroy(info->pool);
 
   info->dir->ref_count--;
@@ -1238,80 +1199,18 @@ handle_propchange_only(report_info_t *in
    server), and feed the information through the associated update
    editor. */
 static svn_error_t *
-local_fetch(report_info_t *info)
+local_fetch(report_info_t *info,
+            apr_pool_t *scratch_pool)
 {
-  const svn_delta_editor_t *update_editor = info->dir->update_editor;
+  SVN_ERR(open_updated_file(info, TRUE, scratch_pool));
 
-  SVN_ERR(open_dir(info->dir));
-  info->editor_pool = svn_pool_create(info->dir->dir_baton_pool);
-
-  /* Expand our full name now if we haven't done so yet. */
-  if (!info->name)
-    {
-      info->name = svn_relpath_join(info->dir->name, info->base_name,
-                                    info->editor_pool);
-    }
-
-  if (SVN_IS_VALID_REVNUM(info->base_rev))
-    {
-      SVN_ERR(update_editor->open_file(info->name,
-                                       info->dir->dir_baton,
-                                       info->base_rev,
-                                       info->editor_pool,
-                                       &info->file_baton));
-    }
-  else
-    {
-      SVN_ERR(update_editor->add_file(info->name,
-                                      info->dir->dir_baton,
-                                      info->copyfrom_path,
-                                      info->copyfrom_rev,
-                                      info->editor_pool,
-                                      &info->file_baton));
-    }
-  
-  SVN_ERR(update_editor->apply_textdelta(info->file_baton,
-                                         info->base_checksum,
-                                         info->editor_pool,
-                                         &info->textdelta,
-                                         &info->textdelta_baton));
-  
   SVN_ERR(svn_txdelta_send_stream(info->cached_contents, info->textdelta,
-                                  info->textdelta_baton, NULL, info->pool));
-
+                                  info->textdelta_baton, NULL, scratch_pool));
   SVN_ERR(svn_stream_close(info->cached_contents));
   info->cached_contents = NULL;
+  SVN_ERR(close_updated_file(info, scratch_pool));
 
-  if (info->lock_token)
-    check_lock(info);
-
-  /* set all of the properties we received */
-  SVN_ERR(svn_ra_serf__walk_all_props(info->props,
-                                      info->base_name,
-                                      info->base_rev,
-                                      set_file_props, info,
-                                      info->pool));
-  
-  SVN_ERR(svn_ra_serf__walk_all_props(info->dir->removed_props,
-                                      info->base_name,
-                                      info->base_rev,
-                                      remove_file_props, info,
-                                      info->pool));
-  if (info->fetch_props)
-    {
-      SVN_ERR(svn_ra_serf__walk_all_props(info->props,
-                                          info->url,
-                                          info->target_rev,
-                                          set_file_props, info,
-                                          info->pool));
-    }
-  
-  SVN_ERR(info->dir->update_editor->close_file(info->file_baton,
-                                               info->final_checksum,
-                                               info->pool));
-  
-  /* We're done with our pools. */
-  svn_pool_destroy(info->editor_pool);
+  /* We're done with our pool. */
   svn_pool_destroy(info->pool);
 
   return SVN_NO_ERROR;
@@ -1326,23 +1225,21 @@ handle_local_fetch(serf_request_t *reque
 {
   report_fetch_t *fetch_ctx = handler_baton;
   apr_status_t status;
-  serf_status_line sl;
   svn_error_t *err;
   const char *data;
   apr_size_t len;
 
+  /* ### new field. make sure we didn't miss some initialization.  */
+  SVN_ERR_ASSERT(fetch_ctx->handler != NULL);
+
   /* If the error code wasn't 200, something went wrong. Don't use the returned
      data as its probably an error message. Just bail out instead. */
-  status = serf_bucket_response_status(response, &sl);
-  if (SERF_BUCKET_READ_ERROR(status))
-    {
-      return svn_error_wrap_apr(status, NULL);
-    }
-  if (sl.code != 200)
+  if (fetch_ctx->handler->sline.code != 200)
     {
       err = svn_error_createf(SVN_ERR_RA_DAV_REQUEST_FAILED, NULL,
                               _("HEAD request failed: %d %s"),
-                              sl.code, sl.reason);
+                              fetch_ctx->handler->sline.code,
+                              fetch_ctx->handler->sline.reason);
       return error_fetch(request, fetch_ctx, err);
     }
 
@@ -1355,7 +1252,7 @@ handle_local_fetch(serf_request_t *reque
         }
       if (APR_STATUS_IS_EOF(status))
         {
-          err = local_fetch(fetch_ctx->info);
+          err = local_fetch(fetch_ctx->info, fetch_ctx->info->pool);
           if (err)
             {
               return error_fetch(request, fetch_ctx, err);
@@ -1474,6 +1371,8 @@ fetch_file(report_context_t *ctx, report
           handler->response_handler = handle_local_fetch;
           handler->response_baton = fetch_ctx;
 
+          fetch_ctx->handler = handler;
+
           svn_ra_serf__request_create(handler);
 
           ctx->active_fetches++;
@@ -1506,6 +1405,8 @@ fetch_file(report_context_t *ctx, report
           handler->response_error = cancel_fetch;
           handler->response_error_baton = fetch_ctx;
 
+          fetch_ctx->handler = handler;
+
           svn_ra_serf__request_create(handler);
 
           ctx->active_fetches++;
@@ -3074,6 +2975,8 @@ svn_ra_serf__get_file(svn_ra_session_t *
       handler->response_error = cancel_fetch;
       handler->response_error_baton = stream_ctx;
 
+      stream_ctx->handler = handler;
+
       svn_ra_serf__request_create(handler);
 
       SVN_ERR(svn_ra_serf__context_run_wait(&stream_ctx->done, session, pool));