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/07/11 12:26:26 UTC

svn commit: r1360103 [5/18] - in /subversion/branches/ev2-export: ./ build/ build/ac-macros/ build/generator/ build/generator/templates/ build/win32/ contrib/server-side/ notes/wc-ng/ subversion/bindings/javahl/native/ subversion/bindings/javahl/src/or...

Modified: subversion/branches/ev2-export/subversion/libsvn_fs_fs/lock.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_fs_fs/lock.c?rev=1360103&r1=1360102&r2=1360103&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_fs_fs/lock.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_fs_fs/lock.c Wed Jul 11 10:26:19 2012
@@ -655,7 +655,11 @@ walk_locks(svn_fs_t *fs,
            svn_boolean_t have_write_lock,
            apr_pool_t *pool)
 {
-  struct walk_locks_baton wlb = { get_locks_func, get_locks_baton, fs };
+  struct walk_locks_baton wlb;
+
+  wlb.get_locks_func = get_locks_func;
+  wlb.get_locks_baton = get_locks_baton;
+  wlb.fs = fs;
   SVN_ERR(walk_digest_files(fs->path, digest_path, locks_walker, &wlb,
                             have_write_lock, pool));
   return SVN_NO_ERROR;

Modified: subversion/branches/ev2-export/subversion/libsvn_fs_fs/rep-cache-db.sql
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_fs_fs/rep-cache-db.sql?rev=1360103&r1=1360102&r2=1360103&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_fs_fs/rep-cache-db.sql (original)
+++ subversion/branches/ev2-export/subversion/libsvn_fs_fs/rep-cache-db.sql Wed Jul 11 10:26:19 2012
@@ -41,25 +41,19 @@ SELECT revision, offset, size, expanded_
 FROM rep_cache
 WHERE hash = ?1
 
-
 -- STMT_SET_REP
 INSERT OR FAIL INTO rep_cache (hash, revision, offset, size, expanded_size)
 VALUES (?1, ?2, ?3, ?4, ?5)
 
-
 -- STMT_GET_REPS_FOR_RANGE
 SELECT hash, revision, offset, size, expanded_size
 FROM rep_cache
 WHERE revision >= ?1 AND revision <= ?2
 
-
 -- STMT_GET_MAX_REV
 SELECT MAX(revision)
 FROM rep_cache
 
-
 -- STMT_DEL_REPS_YOUNGER_THAN_REV
 DELETE FROM rep_cache
 WHERE revision > ?1
-
-

Modified: subversion/branches/ev2-export/subversion/libsvn_fs_fs/structure
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_fs_fs/structure?rev=1360103&r1=1360102&r2=1360103&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_fs_fs/structure (original)
+++ subversion/branches/ev2-export/subversion/libsvn_fs_fs/structure Wed Jul 11 10:26:19 2012
@@ -40,6 +40,9 @@ repository) is:
   revprops/           Subdirectory containing rev-props
     <shard>/          Shard directory, if sharding is in use (see below)
       <revnum>        File containing rev-props for <revnum>
+    <shard>.pack/     Pack directory, if the repo has been packed (see below)
+      <rev>.<count>   Pack file, if the repository has been packed (see below)
+      manifest        Pack manifest file, if a pack file exists (see below)
     revprops.db       SQLite database of the packed revision properties
   transactions/       Subdirectory containing transactions
     <txnid>.txn/      Directory containing transaction <txnid>
@@ -134,6 +137,7 @@ The formats are:
   Format 3, understood by Subversion 1.5+
   Format 4, understood by Subversion 1.6+
   Format 5, understood by Subversion 1.7-dev, never released
+  Format 6, understood by Subversion 1.8
 
 The differences between the formats are:
 
@@ -173,6 +177,12 @@ Revision changed paths list:
   Format 1-3: Does not contain the node's kind.
   Format 4+:  Contains the node's kind.
 
+Shard packing:
+  Format 4:   Applied to revision data only.
+  Format 5:   Revprops would be packed independently of revision data.
+  Format 6+:  Applied equally to revision data and revprop data
+    (i.e. same min packed revision)
+
 # Incomplete list.  See SVN_FS_FS__MIN_*_FORMAT
 
 
@@ -232,6 +242,79 @@ See r1143829 of this file:
 http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_fs/structure?view=markup&pathrev=1143829
 
 
+Packing revision properties (format 6+)
+---------------------------
+
+Similarly to the revision data, packing will concatenate multiple
+revprops into a single file.  Since they are mutable data, we put an
+upper limit to the size of these files:  We will concatenate the data
+up to the limit and then use a new file for the following revisions.
+
+The limit can be set and changed at will in the configuration file. 
+It is 64kB by default.  Because a pack file must contain at least one
+complete property list, files containing just one revision may exceed
+that limit.
+
+Furthermore, pack files can be compressed which saves about 75% of
+disk space.  A configuration file flag enables the compression; it is
+off by default and may be switched on and off at will.  The pack size
+limit is always applied to the uncompressed data.  For this reason,
+the default is 256kB while compression has been enabled.
+
+Files are named after their start revision as "<rev>.<counter>" where
+counter will be increased whenever we rewrite a pack file due to a
+revprop change.  The manifest file contains the list of pack file
+names, one line for each revision.
+
+Many tools track repository global data in revision properties at 
+revision 0.  To minimize I/O overhead for those applications,  we
+will never pack that revision, i.e. its data is always being kept
+in revprops/0/0.
+
+Pack file format
+
+  Top level: <length><packed container>
+
+  We always apply data compression to the pack file - using the
+  SVN_DELTA_COMPRESSION_LEVEL_NONE level if compression is disabled.
+  <length> is being encoded using the variable-length svndiff integer
+  format.
+
+  container := header '\n' (revprops)+
+  header    := start_rev '\n' rev_count '\n' (size '\n')+
+
+  All numbers in the header are given as ASCII decimals.  rev_count
+  is the number of revisions packed into this container.  There must
+  be exactly as many "size" and serialized "revprops".  The "size"
+  values in the list are the length in bytes of the serialized
+  revprops of the respective revision.
+
+Writing to packed revprops
+
+  The old pack file is being read and the new revprops serialized.
+  If they fit into the same pack file, a temp file with the new
+  content gets written and moved into place just like an non-packed
+  revprop file would. No name change or manifest update required.
+
+  If they don't fit into the same pack file,  i.e. exceed the pack
+  size limit,  the pack will be split into 2 or 3 new packs just
+  before and / or after the modified revision.
+
+  In the current implementation, they will never be merged again.
+  To minimize fragmentation, the initial packing process will only
+  use about 90% of the limit, i.e. leave some room for growth.
+
+  When a pack file gets split, its counter is being increased
+  creating a new file and leaving the old content in place and
+  available for concurrent readers.  Only after the new manifest
+  file got moved into place, will the old pack files be deleted. 
+
+  Write access to revprops is being serialized by the global
+  filesystem write lock.  We only need to build a few retries into
+  the reader code to gracefully handle manifest changes and pack
+  file deletions.
+
+
 Node-revision IDs
 -----------------
 

Modified: subversion/branches/ev2-export/subversion/libsvn_fs_fs/temp_serializer.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_fs_fs/temp_serializer.c?rev=1360103&r1=1360102&r2=1360103&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_fs_fs/temp_serializer.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_fs_fs/temp_serializer.c Wed Jul 11 10:26:19 2012
@@ -48,16 +48,16 @@ encode_number(apr_int64_t number, char *
   if (number < 0)
   {
     number = -number;
-    *key_buffer = (number & 63) + ' ' + 65;
+    *key_buffer = (char)((number & 63) + ' ' + 65);
   }
   else
-    *key_buffer = (number & 63) + ' ' + 1;
+    *key_buffer = (char)((number & 63) + ' ' + 1);
   number /= 64;
 
   /* write 7 bits / byte until no significant bits are left */
   while (number)
   {
-    *++key_buffer = (number & 127) + ' ' + 1;
+    *++key_buffer = (char)((number & 127) + ' ' + 1);
     number /= 128;
   }
 

Modified: subversion/branches/ev2-export/subversion/libsvn_fs_fs/tree.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_fs_fs/tree.c?rev=1360103&r1=1360102&r2=1360103&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_fs_fs/tree.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_fs_fs/tree.c Wed Jul 11 10:26:19 2012
@@ -3881,6 +3881,7 @@ svn_fs_fs__verify_root(svn_fs_root_t *ro
     const svn_fs_id_t *pred_id;
     dag_node_t *pred;
     svn_revnum_t pred_rev;
+    svn_revnum_t delta;
 
     /* Only r0 should have no predecessor. */
     SVN_ERR(svn_fs_fs__dag_get_predecessor_id(&pred_id, frd->root_dir));
@@ -3898,10 +3899,27 @@ svn_fs_fs__verify_root(svn_fs_root_t *ro
       {
         SVN_ERR(svn_fs_fs__dag_get_node(&pred, root->fs, pred_id, pool));
         SVN_ERR(svn_fs_fs__dag_get_revision(&pred_rev, pred, pool));
-        if (pred_rev+1 != root->rev)
-          /* Issue #4129. */
+
+        /* Issue #4129: bogus predecessors. */
+        /* Check 1: predecessor must be an earlier revision.
+         */
+        if (pred_rev >= root->rev)
+          return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
+                                   "r%ld's root node's predecessor is r%ld"
+                                   " but must be earlier revision",
+                                   root->rev, pred_rev);
+
+        /* Check 2: distances must be a power of 2.
+         * Note that this condition is not defined by the FSFS format but
+         * merely a byproduct of the current implementation. Therefore,
+         * it may help to spot corruptions for the time being but might
+         * need to be removed / relaxed in later versions.
+         */
+        delta = root->rev - pred_rev;
+        if (delta & (delta - 1))
           return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
-                                   "r%ld's root node's predecessor is r%ld",
+                                   "r%ld's root node's predecessor is r%ld"
+                                   " but the delta must be a power of 2",
                                    root->rev, pred_rev);
       }
   }

Modified: subversion/branches/ev2-export/subversion/libsvn_ra/ra_loader.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra/ra_loader.c?rev=1360103&r1=1360102&r2=1360103&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra/ra_loader.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra/ra_loader.c Wed Jul 11 10:26:19 2012
@@ -51,20 +51,6 @@
 #include "private/svn_delta_private.h"
 
 
-/* ### This file maps URL schemes to particular RA libraries.
-   ### Currently, the only pair of RA libraries which support the same
-   ### protocols are neon and serf.  svn_ra_open3 makes the assumption
-   ### that this is the case; that their 'schemes' fields are both
-   ### dav_schemes; and that "neon" is listed first.
-
-   ### Users can choose which dav library to use with the http-library
-   ### preference in .subversion/servers; however, it is ignored by
-   ### any code which uses the pre-1.2 API svn_ra_get_ra_library
-   ### instead of svn_ra_open. */
-
-#if defined(SVN_HAVE_NEON) && defined(SVN_HAVE_SERF)
-#define CHOOSABLE_DAV_MODULE
-#endif
 
 
 /* These are the URI schemes that the respective libraries *may* support.
@@ -86,15 +72,6 @@ static const struct ra_lib_defn {
   svn_ra_init_func_t compat_initfunc;
 } ra_libraries[] = {
   {
-    "neon",
-    dav_schemes,
-#ifdef SVN_LIBSVN_CLIENT_LINKS_RA_NEON
-    svn_ra_neon__init,
-    svn_ra_dav_init
-#endif
-  },
-
-  {
     "svn",
     svn_schemes,
 #ifdef SVN_LIBSVN_CLIENT_LINKS_RA_SVN
@@ -414,8 +391,7 @@ svn_error_t *svn_ra_open4(svn_ra_session
                                             SVN_CONFIG_OPTION_HTTP_LIBRARY,
                                             DEFAULT_HTTP_LIBRARY);
 
-          if (strcmp(http_library, "neon") != 0 &&
-              strcmp(http_library, "serf") != 0)
+          if (strcmp(http_library, "serf") != 0)
             return svn_error_createf(SVN_ERR_BAD_CONFIG_VALUE, NULL,
                                      _("Invalid config: unknown HTTP library "
                                        "'%s'"),
@@ -1282,8 +1258,7 @@ svn_ra_get_deleted_rev(svn_ra_session_t 
                                          end_revision,
                                          revision_deleted,
                                          pool);
-  if (err && (err->apr_err == SVN_ERR_UNSUPPORTED_FEATURE     /* serf */
-              || err->apr_err == SVN_ERR_RA_NOT_IMPLEMENTED)) /* neon */
+  if (err && (err->apr_err == SVN_ERR_UNSUPPORTED_FEATURE))
     {
       svn_error_clear(err);
 

Modified: subversion/branches/ev2-export/subversion/libsvn_ra/ra_loader.h
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra/ra_loader.h?rev=1360103&r1=1360102&r2=1360103&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra/ra_loader.h (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra/ra_loader.h Wed Jul 11 10:26:19 2012
@@ -353,9 +353,6 @@ svn_error_t *svn_ra_local__init(const sv
 svn_error_t *svn_ra_svn__init(const svn_version_t *loader_version,
                               const svn_ra__vtable_t **vtable,
                               apr_pool_t *pool);
-svn_error_t *svn_ra_neon__init(const svn_version_t *loader_version,
-                              const svn_ra__vtable_t **vtable,
-                              apr_pool_t *pool);
 svn_error_t *svn_ra_serf__init(const svn_version_t *loader_version,
                                const svn_ra__vtable_t **vtable,
                                apr_pool_t *pool);

Modified: subversion/branches/ev2-export/subversion/libsvn_ra_serf/blame.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra_serf/blame.c?rev=1360103&r1=1360102&r2=1360103&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra_serf/blame.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra_serf/blame.c Wed Jul 11 10:26:19 2012
@@ -46,7 +46,6 @@
  * This enum represents the current state of our XML parsing for a REPORT.
  */
 typedef enum blame_state_e {
-  NONE = 0,
   INITIAL = 0,
   FILE_REVS_REPORT,
   FILE_REV,
@@ -57,40 +56,6 @@ typedef enum blame_state_e {
   TXDELTA
 } blame_state_e;
 
-typedef struct blame_info_t {
-  /* Current pool. */
-  apr_pool_t *pool;
-
-  /* our suspicious file */
-  const char *path;
-
-  /* the intended suspect */
-  svn_revnum_t rev;
-
-  /* Hashtable of revision properties */
-  apr_hash_t *rev_props;
-
-  /* Added and removed properties (svn_prop_t*'s) */
-  apr_array_header_t *prop_diffs;
-
-  /* txdelta */
-  svn_txdelta_window_handler_t txdelta;
-  void *txdelta_baton;
-
-  /* returned txdelta stream */
-  svn_stream_t *stream;
-
-  /* Is this property base64-encoded? */
-  svn_boolean_t prop_base64;
-
-  /* The currently collected value as we build it up */
-  const char *prop_name;
-  svn_stringbuf_t *prop_value;
-
-  /* Merged revision flag */
-  svn_boolean_t merged_revision;
-
-} blame_info_t;
 
 typedef struct blame_context_t {
   /* pool passed to get_file_revs */
@@ -102,19 +67,21 @@ typedef struct blame_context_t {
   svn_revnum_t end;
   svn_boolean_t include_merged_revisions;
 
-  /* are we done? */
-  svn_boolean_t done;
-
   /* blame handler and baton */
   svn_file_rev_handler_t file_rev;
   void *file_rev_baton;
-} blame_context_t;
 
+  /* As we parse each FILE_REV, we collect data in these variables:
+     property changes and new content.  STREAM is valid when we're
+     in the TXDELTA state, processing the incoming cdata.  */
+  apr_hash_t *rev_props;
+  apr_array_header_t *prop_diffs;
+  apr_pool_t *state_pool;  /* put property stuff in here  */
+
+  svn_stream_t *stream;
+
+} blame_context_t;
 
-#if 0
-/* ### we cannot use this yet since the CDATA is unbounded and cannot be
-   ### collected by the parsing context. we need a streamy mechanism for
-   ### this report.  */
 
 #define D_ "DAV:"
 #define S_ SVN_XML_NAMESPACE
@@ -125,285 +92,188 @@ static const svn_ra_serf__xml_transition
   { FILE_REVS_REPORT, S_, "file-rev", FILE_REV,
     FALSE, { "path", "rev", NULL }, TRUE },
 
-  { FILE_REV, D_, "rev-prop", REV_PROP,
+  { FILE_REV, S_, "rev-prop", REV_PROP,
     TRUE, { "name", "?encoding", NULL }, TRUE },
 
-  { FILE_REV, D_, "set-prop", SET_PROP,
+  { FILE_REV, S_, "set-prop", SET_PROP,
     TRUE, { "name", "?encoding", NULL }, TRUE },
 
-  { FILE_REV, D_, "remove-prop", REMOVE_PROP,
-    FALSE, { "name", "?encoding", NULL }, TRUE },
+  { FILE_REV, S_, "remove-prop", REMOVE_PROP,
+    FALSE, { "name", NULL }, TRUE },
 
-  { FILE_REV, D_, "merged-revision", MERGED_REVISION,
-    FALSE, { NULL }, FALSE },
+  { FILE_REV, S_, "merged-revision", MERGED_REVISION,
+    FALSE, { NULL }, TRUE },
 
-  { FILE_REV, D_, "txdelta", TXDELTA,
-    TRUE, { NULL }, TRUE },
+  { FILE_REV, S_, "txdelta", TXDELTA,
+    FALSE, { NULL }, TRUE },
 
   { 0 }
 };
 
-#endif
-
 
-
-static blame_info_t *
-push_state(svn_ra_serf__xml_parser_t *parser,
-           blame_context_t *blame_ctx,
-           blame_state_e state)
+/* Conforms to svn_ra_serf__xml_opened_t  */
+static svn_error_t *
+blame_opened(svn_ra_serf__xml_estate_t *xes,
+             void *baton,
+             int entered_state,
+             const svn_ra_serf__dav_props_t *tag,
+             apr_pool_t *scratch_pool)
 {
-  svn_ra_serf__xml_push_state(parser, state);
+  blame_context_t *blame_ctx = baton;
 
-  if (state == FILE_REV)
+  if (entered_state == FILE_REV)
     {
-      blame_info_t *info;
-
-      info = apr_pcalloc(parser->state->pool, sizeof(*info));
-
-      info->pool = parser->state->pool;
-
-      info->rev = SVN_INVALID_REVNUM;
+      apr_pool_t *state_pool = svn_ra_serf__xml_state_pool(xes);
 
-      info->rev_props = apr_hash_make(info->pool);
-      info->prop_diffs = apr_array_make(info->pool, 0, sizeof(svn_prop_t));
-
-      info->prop_value = svn_stringbuf_create_empty(info->pool);
-
-      parser->state->private = info;
+      /* Child elements will store properties in these structures.  */
+      blame_ctx->rev_props = apr_hash_make(state_pool);
+      blame_ctx->prop_diffs = apr_array_make(state_pool,
+                                             5, sizeof(svn_prop_t));
+      blame_ctx->state_pool = state_pool;
+
+      /* Clear this, so we can detect the absence of a TXDELTA.  */
+      blame_ctx->stream = NULL;
+    }
+  else if (entered_state == TXDELTA)
+    {
+      apr_pool_t *state_pool = svn_ra_serf__xml_state_pool(xes);
+      apr_hash_t *gathered = svn_ra_serf__xml_gather_since(xes, FILE_REV);
+      const char *path;
+      const char *rev;
+      const char *merged_revision;
+      svn_txdelta_window_handler_t txdelta;
+      void *txdelta_baton;
+
+      path = apr_hash_get(gathered, "path", APR_HASH_KEY_STRING);
+      rev = apr_hash_get(gathered, "rev", APR_HASH_KEY_STRING);
+      merged_revision = apr_hash_get(gathered,
+                                     "merged-revision", APR_HASH_KEY_STRING);
+
+      SVN_ERR(blame_ctx->file_rev(blame_ctx->file_rev_baton,
+                                  path, SVN_STR_TO_REV(rev),
+                                  blame_ctx->rev_props,
+                                  merged_revision != NULL,
+                                  &txdelta, &txdelta_baton,
+                                  blame_ctx->prop_diffs,
+                                  state_pool));
+
+      blame_ctx->stream = svn_base64_decode(svn_txdelta_parse_svndiff(
+                                              txdelta, txdelta_baton,
+                                              TRUE /* error_on_early_close */,
+                                              state_pool),
+                                            state_pool);
     }
 
-  return parser->state->private;
+  return SVN_NO_ERROR;
 }
 
 
-static const svn_string_t *
-create_propval(blame_info_t *info)
-{
-  if (info->prop_base64)
-    {
-      const svn_string_t *morph;
-
-      morph = svn_stringbuf__morph_into_string(info->prop_value);
-#ifdef SVN_DEBUG
-      info->prop_value = NULL;  /* morph killed the stringbuf.  */
-#endif
-      return svn_base64_decode_string(morph, info->pool);
-    }
-
-  return svn_string_create_from_buf(info->prop_value, info->pool);
-}
-
+/* Conforms to svn_ra_serf__xml_closed_t  */
 static svn_error_t *
-start_blame(svn_ra_serf__xml_parser_t *parser,
-            svn_ra_serf__dav_props_t name,
-            const char **attrs,
-            apr_pool_t *scratch_pool)
+blame_closed(svn_ra_serf__xml_estate_t *xes,
+             void *baton,
+             int leaving_state,
+             const svn_string_t *cdata,
+             apr_hash_t *attrs,
+             apr_pool_t *scratch_pool)
 {
-  blame_context_t *blame_ctx = parser->user_data;
-  blame_state_e state;
+  blame_context_t *blame_ctx = baton;
+
+  if (leaving_state == FILE_REV)
+    {
+      /* Note that we test STREAM, but any pointer is currently invalid.
+         It was closed when left the TXDELTA state.  */
+      if (blame_ctx->stream == NULL)
+        {
+          const char *path;
+          const char *rev;
 
-  state = parser->state->current_state;
+          path = apr_hash_get(attrs, "path", APR_HASH_KEY_STRING);
+          rev = apr_hash_get(attrs, "rev", APR_HASH_KEY_STRING);
 
-  if (state == NONE && strcmp(name.name, "file-revs-report") == 0)
+          /* Send a "no content" notification.  */
+          SVN_ERR(blame_ctx->file_rev(blame_ctx->file_rev_baton,
+                                      path, SVN_STR_TO_REV(rev),
+                                      blame_ctx->rev_props,
+                                      FALSE /* result_of_merge */,
+                                      NULL, NULL, /* txdelta / baton */
+                                      blame_ctx->prop_diffs,
+                                      scratch_pool));
+        }
+    }
+  else if (leaving_state == MERGED_REVISION)
     {
-      push_state(parser, blame_ctx, FILE_REVS_REPORT);
+      svn_ra_serf__xml_note(xes, FILE_REV, "merged-revision", "*");
     }
-  else if (state == FILE_REVS_REPORT &&
-           strcmp(name.name, "file-rev") == 0)
+  else if (leaving_state == TXDELTA)
     {
-      blame_info_t *info;
-
-      info = push_state(parser, blame_ctx, FILE_REV);
-
-      info->path = apr_pstrdup(info->pool,
-                               svn_xml_get_attr_value("path", attrs));
-      info->rev = SVN_STR_TO_REV(svn_xml_get_attr_value("rev", attrs));
+      SVN_ERR(svn_stream_close(blame_ctx->stream));
     }
-  else if (state == FILE_REV)
+  else
     {
-      blame_info_t *info;
-      const char *enc;
+      const char *name;
+      const svn_string_t *value;
 
-      info = parser->state->private;
+      SVN_ERR_ASSERT(leaving_state == REV_PROP
+                     || leaving_state == SET_PROP
+                     || leaving_state == REMOVE_PROP);
 
-      if (strcmp(name.name, "rev-prop") == 0)
-        {
-          push_state(parser, blame_ctx, REV_PROP);
-        }
-      else if (strcmp(name.name, "set-prop") == 0)
-        {
-          push_state(parser, blame_ctx, SET_PROP);
-        }
-      if (strcmp(name.name, "remove-prop") == 0)
-        {
-          push_state(parser, blame_ctx, REMOVE_PROP);
-        }
-      else if (strcmp(name.name, "merged-revision") == 0)
+      name = apr_pstrdup(blame_ctx->state_pool,
+                         apr_hash_get(attrs, "name", APR_HASH_KEY_STRING));
+
+      if (leaving_state == REMOVE_PROP)
         {
-          push_state(parser, blame_ctx, MERGED_REVISION);
+          value = NULL;
         }
-      else if (strcmp(name.name, "txdelta") == 0)
+      else
         {
-          SVN_ERR(blame_ctx->file_rev(blame_ctx->file_rev_baton,
-                                      info->path, info->rev,
-                                      info->rev_props, info->merged_revision,
-                                      &info->txdelta, &info->txdelta_baton,
-                                      info->prop_diffs, info->pool));
-
-          info->stream = svn_base64_decode
-              (svn_txdelta_parse_svndiff(info->txdelta, info->txdelta_baton,
-                                         TRUE, info->pool), info->pool);
+          const char *encoding = apr_hash_get(attrs,
+                                              "encoding", APR_HASH_KEY_STRING);
 
-          push_state(parser, blame_ctx, TXDELTA);
-        }
-
-      state = parser->state->current_state;
-
-      switch (state)
-        {
-        case REV_PROP:
-        case SET_PROP:
-        case REMOVE_PROP:
-          info->prop_name = apr_pstrdup(info->pool,
-                                        svn_xml_get_attr_value("name", attrs));
-          svn_stringbuf_setempty(info->prop_value);
-
-          enc = svn_xml_get_attr_value("encoding", attrs);
-          if (enc && strcmp(enc, "base64") == 0)
-            {
-              info->prop_base64 = TRUE;
-            }
+          if (encoding && strcmp(encoding, "base64") == 0)
+            value = svn_base64_decode_string(cdata, blame_ctx->state_pool);
           else
-            {
-              info->prop_base64 = FALSE;
-            }
-          break;
-        case MERGED_REVISION:
-            info->merged_revision = TRUE;
-          break;
-        default:
-          break;
+            value = svn_string_dup(cdata, blame_ctx->state_pool);
         }
-    }
 
-  return SVN_NO_ERROR;
-}
-
-static svn_error_t *
-end_blame(svn_ra_serf__xml_parser_t *parser,
-          svn_ra_serf__dav_props_t name,
-          apr_pool_t *scratch_pool)
-{
-  blame_context_t *blame_ctx = parser->user_data;
-  blame_state_e state;
-  blame_info_t *info;
-
-  state = parser->state->current_state;
-  info = parser->state->private;
-
-  if (state == NONE)
-    {
-      return SVN_NO_ERROR;
-    }
-
-  if (state == FILE_REVS_REPORT &&
-      strcmp(name.name, "file-revs-report") == 0)
-    {
-      svn_ra_serf__xml_pop_state(parser);
-    }
-  else if (state == FILE_REV &&
-           strcmp(name.name, "file-rev") == 0)
-    {
-      /* no file changes. */
-      if (!info->stream)
+      if (leaving_state == REV_PROP)
         {
-          SVN_ERR(blame_ctx->file_rev(blame_ctx->file_rev_baton,
-                                      info->path, info->rev,
-                                      info->rev_props, FALSE,
-                                      NULL, NULL,
-                                      info->prop_diffs, info->pool));
+          apr_hash_set(blame_ctx->rev_props, name, APR_HASH_KEY_STRING, value);
         }
-      svn_ra_serf__xml_pop_state(parser);
-    }
-  else if (state == REV_PROP &&
-           strcmp(name.name, "rev-prop") == 0)
-    {
-      apr_hash_set(info->rev_props,
-                   info->prop_name, APR_HASH_KEY_STRING,
-                   create_propval(info));
-
-      svn_ra_serf__xml_pop_state(parser);
-    }
-  else if ((state == SET_PROP &&
-            strcmp(name.name, "set-prop") == 0) ||
-           (state == REMOVE_PROP &&
-            strcmp(name.name, "remove-prop") == 0))
-    {
-      svn_prop_t *prop = apr_array_push(info->prop_diffs);
-      prop->name = info->prop_name;
-      prop->value = create_propval(info);
-
-      svn_ra_serf__xml_pop_state(parser);
-    }
-  else if (state == MERGED_REVISION &&
-           strcmp(name.name, "merged-revision") == 0)
-    {
-      svn_ra_serf__xml_pop_state(parser);
-    }
-  else if (state == TXDELTA &&
-           strcmp(name.name, "txdelta") == 0)
-    {
-      SVN_ERR(svn_stream_close(info->stream));
+      else
+        {
+          svn_prop_t *prop = apr_array_push(blame_ctx->prop_diffs);
 
-      svn_ra_serf__xml_pop_state(parser);
+          prop->name = name;
+          prop->value = value;
+        }
     }
 
   return SVN_NO_ERROR;
 }
 
+
+/* Conforms to svn_ra_serf__xml_cdata_t  */
 static svn_error_t *
-cdata_blame(svn_ra_serf__xml_parser_t *parser,
+blame_cdata(svn_ra_serf__xml_estate_t *xes,
+            void *baton,
+            int current_state,
             const char *data,
             apr_size_t len,
             apr_pool_t *scratch_pool)
 {
-  blame_context_t *blame_ctx = parser->user_data;
-  blame_state_e state;
-  blame_info_t *info;
-
-  UNUSED_CTX(blame_ctx);
-
-  state = parser->state->current_state;
-  info = parser->state->private;
-
-  if (state == NONE)
-    {
-      return SVN_NO_ERROR;
-    }
+  blame_context_t *blame_ctx = baton;
 
-  switch (state)
+  if (current_state == TXDELTA)
     {
-      case REV_PROP:
-      case SET_PROP:
-        svn_stringbuf_appendbytes(info->prop_value, data, len);
-        break;
-      case TXDELTA:
-        if (info->stream)
-          {
-            apr_size_t ret_len;
-
-            ret_len = len;
-
-            SVN_ERR(svn_stream_write(info->stream, data, &ret_len));
-          }
-        break;
-      default:
-        break;
+      SVN_ERR(svn_stream_write(blame_ctx->stream, data, &len));
+      /* Ignore the returned LEN value.  */
     }
 
   return SVN_NO_ERROR;
 }
 
+
 /* Implements svn_ra_serf__request_body_delegate_t */
 static svn_error_t *
 create_file_revs_body(serf_bucket_t **body_bkt,
@@ -460,7 +330,7 @@ svn_ra_serf__get_file_revs(svn_ra_sessio
   blame_context_t *blame_ctx;
   svn_ra_serf__session_t *session = ra_session->priv;
   svn_ra_serf__handler_t *handler;
-  svn_ra_serf__xml_parser_t *parser_ctx;
+  svn_ra_serf__xml_context_t *xmlctx;
   const char *req_url;
   svn_error_t *err;
 
@@ -472,16 +342,20 @@ svn_ra_serf__get_file_revs(svn_ra_sessio
   blame_ctx->start = start;
   blame_ctx->end = end;
   blame_ctx->include_merged_revisions = include_merged_revisions;
-  blame_ctx->done = FALSE;
 
   SVN_ERR(svn_ra_serf__get_stable_url(&req_url, NULL /* latest_revnum */,
                                       session, NULL /* conn */,
                                       NULL /* url */, end,
                                       pool, pool));
 
-  handler = apr_pcalloc(pool, sizeof(*handler));
+  xmlctx = svn_ra_serf__xml_context_create(blame_ttable,
+                                           blame_opened,
+                                           blame_closed,
+                                           blame_cdata,
+                                           blame_ctx,
+                                           pool);
+  handler = svn_ra_serf__create_expat_handler(xmlctx, pool);
 
-  handler->handler_pool = pool;
   handler->method = "REPORT";
   handler->path = req_url;
   handler->body_type = "text/xml";
@@ -490,21 +364,7 @@ svn_ra_serf__get_file_revs(svn_ra_sessio
   handler->conn = session->conns[0];
   handler->session = session;
 
-  parser_ctx = apr_pcalloc(pool, sizeof(*parser_ctx));
-
-  parser_ctx->pool = pool;
-  parser_ctx->user_data = blame_ctx;
-  parser_ctx->start = start_blame;
-  parser_ctx->end = end_blame;
-  parser_ctx->cdata = cdata_blame;
-  parser_ctx->done = &blame_ctx->done;
-
-  handler->response_handler = svn_ra_serf__handle_xml_parser;
-  handler->response_baton = parser_ctx;
-
-  svn_ra_serf__request_create(handler);
-
-  err = svn_ra_serf__context_run_wait(&blame_ctx->done, session, pool);
+  err = svn_ra_serf__context_run_one(handler, pool);
 
   err = svn_error_compose_create(
             svn_ra_serf__error_on_status(handler->sline.code,

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=1360103&r1=1360102&r2=1360103&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra_serf/commit.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra_serf/commit.c Wed Jul 11 10:26:19 2012
@@ -42,22 +42,6 @@
 #include "ra_serf.h"
 #include "../libsvn_ra/ra_loader.h"
 
-
-/* Structure associated with a CHECKOUT request. */
-typedef struct checkout_context_t {
-  /* The handler running the CHECKOUT.  */
-  svn_ra_serf__handler_t *handler;
-
-  /* The pool for allocating RESOURCE_URL.  */
-  apr_pool_t *result_pool;
-
-  /* The activity that will hold the checked-out resource.  */
-  const char *activity_url;
-
-  /* The output:  */
-  const char *resource_url;
-
-} checkout_context_t;
 
 /* Baton passed back with the commit editor. */
 typedef struct commit_context_t {
@@ -250,7 +234,7 @@ create_checkout_body(serf_bucket_t **bkt
                      serf_bucket_alloc_t *alloc,
                      apr_pool_t *pool)
 {
-  checkout_context_t *ctx = baton;
+  const char *activity_url = baton;
   serf_bucket_t *body_bkt;
 
   body_bkt = serf_bucket_aggregate_create(alloc);
@@ -262,10 +246,10 @@ create_checkout_body(serf_bucket_t **bkt
   svn_ra_serf__add_open_tag_buckets(body_bkt, alloc, "D:activity-set", NULL);
   svn_ra_serf__add_open_tag_buckets(body_bkt, alloc, "D:href", NULL);
 
-  SVN_ERR_ASSERT(ctx->activity_url != NULL);
+  SVN_ERR_ASSERT(activity_url != NULL);
   svn_ra_serf__add_cdata_len_buckets(body_bkt, alloc,
-                                     ctx->activity_url,
-                                     strlen(ctx->activity_url));
+                                     activity_url,
+                                     strlen(activity_url));
 
   svn_ra_serf__add_close_tag_buckets(body_bkt, alloc, "D:href");
   svn_ra_serf__add_close_tag_buckets(body_bkt, alloc, "D:activity-set");
@@ -276,53 +260,6 @@ create_checkout_body(serf_bucket_t **bkt
   return SVN_NO_ERROR;
 }
 
-/* Implements svn_ra_serf__response_handler_t */
-static svn_error_t *
-handle_checkout(serf_request_t *request,
-                serf_bucket_t *response,
-                void *baton,
-                apr_pool_t *pool)
-{
-  checkout_context_t *ctx = baton;
-  svn_ra_serf__handler_t *handler = ctx->handler;
-
-  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
-     completely read. While we have to return this status code to our
-     caller, we should treat it as the normal case for now. */
-  if (err && ! APR_STATUS_IS_EOF(err->apr_err))
-    return err;
-
-  /* Get the resulting location. */
-  if (handler->done && handler->sline.code == 201)
-    {
-      serf_bucket_t *hdrs;
-      apr_uri_t uri;
-      const char *location;
-      apr_status_t status;
-
-      hdrs = serf_bucket_response_get_headers(response);
-      location = serf_bucket_headers_get(hdrs, "Location");
-      if (!location)
-        return svn_error_create(SVN_ERR_RA_DAV_MALFORMED_DATA, err,
-                                _("No Location header received"));
-
-      status = apr_uri_parse(pool, location, &uri);
-
-      if (status)
-        err = svn_error_compose_create(svn_error_wrap_apr(status, NULL), err);
-
-      SVN_ERR_ASSERT(ctx->result_pool != NULL);
-      ctx->resource_url = svn_urlpath__canonicalize(uri.path,
-                                                    ctx->result_pool);
-    }
-
-  return err;
-}
-
 
 /* Using the HTTPv1 protocol, perform a CHECKOUT of NODE_URL within the
    given COMMIT_CTX. The resulting working resource will be returned in
@@ -351,7 +288,6 @@ checkout_node(const char **working_url,
               apr_pool_t *scratch_pool)
 {
   svn_ra_serf__handler_t handler = { 0 };
-  checkout_context_t checkout_ctx = { 0 };
 
   /* HANDLER_POOL is the scratch pool since we don't need to remember
      anything from the handler. We just want the working resource.  */
@@ -359,16 +295,12 @@ checkout_node(const char **working_url,
   handler.session = commit_ctx->session;
   handler.conn = commit_ctx->conn;
 
-  checkout_ctx.handler = &handler;
-  checkout_ctx.result_pool = result_pool;
-  checkout_ctx.activity_url = commit_ctx->activity_url;
-
   handler.body_delegate = create_checkout_body;
-  handler.body_delegate_baton = &checkout_ctx;
+  handler.body_delegate_baton = (/* const */ void *)commit_ctx->activity_url;
   handler.body_type = "text/xml";
 
-  handler.response_handler = handle_checkout;
-  handler.response_baton = &checkout_ctx;
+  handler.response_handler = svn_ra_serf__expect_empty_body;
+  handler.response_baton = &handler;
 
   handler.method = "CHECKOUT";
   handler.path = node_url;
@@ -378,8 +310,11 @@ checkout_node(const char **working_url,
   if (handler.sline.code != 201)
     return svn_error_trace(return_response_err(&handler));
 
-  /* Already in the correct pool.  */
-  *working_url = checkout_ctx.resource_url;
+  if (handler.location == NULL)
+    return svn_error_create(SVN_ERR_RA_DAV_MALFORMED_DATA, NULL,
+                            _("No Location header received"));
+
+  *working_url = apr_pstrdup(result_pool, handler.location);
 
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/ev2-export/subversion/libsvn_ra_serf/options.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra_serf/options.c?rev=1360103&r1=1360102&r2=1360103&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra_serf/options.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra_serf/options.c Wed Jul 11 10:26:19 2012
@@ -450,9 +450,7 @@ svn_ra_serf__has_capability(svn_ra_sessi
   cap_result = apr_hash_get(serf_sess->capabilities,
                             capability, APR_HASH_KEY_STRING);
 
-  /* Some capabilities depend on the repository as well as the server.
-     NOTE: svn_ra_neon__has_capability() has a very similar code block.  If
-     you change something here, check there as well. */
+  /* Some capabilities depend on the repository as well as the server. */
   if (cap_result == capability_server_yes)
     {
       if (strcmp(capability, SVN_RA_CAPABILITY_MERGEINFO) == 0)

Modified: subversion/branches/ev2-export/subversion/libsvn_ra_serf/property.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra_serf/property.c?rev=1360103&r1=1360102&r2=1360103&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra_serf/property.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra_serf/property.c Wed Jul 11 10:26:19 2012
@@ -41,28 +41,23 @@
 
 /* Our current parsing state we're in for the PROPFIND response. */
 typedef enum prop_state_e {
-  NONE = 0,
+  INITIAL = 0,
+  MULTISTATUS,
   RESPONSE,
+  HREF,
+  PROPSTAT,
+  STATUS,
   PROP,
-  PROPVAL
+  PROPVAL,
+  COLLECTION,
+  HREF_VALUE
 } prop_state_e;
 
-typedef struct prop_info_t {
-  apr_pool_t *pool;
-
-  /* Current ns, attribute name, and value of the property we're parsing */
-  const char *ns;
-  const char *name;
-  svn_stringbuf_t *value;
-
-  const char *encoding;
-
-} prop_info_t;
 
 /*
  * This structure represents a pending PROPFIND response.
  */
-struct svn_ra_serf__propfind_context_t {
+typedef struct propfind_context_t {
   /* pool to issue allocations from */
   apr_pool_t *pool;
 
@@ -87,29 +82,273 @@ struct svn_ra_serf__propfind_context_t {
 
   /* hash table that will be updated with the properties
    *
-   * This can be shared between multiple svn_ra_serf__propfind_context_t
+   * This can be shared between multiple propfind_context_t
    * structures
    */
   apr_hash_t *ret_props;
 
-  /* If we're dealing with a Depth: 1 response,
-   * we may be dealing with multiple paths.
+  /* hash table containing all the properties associated with the
+   * "current" <propstat> tag.  These will get copied into RET_PROPS
+   * if the status code similarly associated indicates that they are
+   * "good"; otherwise, they'll get discarded.
    */
-  const char *current_path;
-
-  /* Are we done issuing the PROPFIND? */
-  svn_boolean_t done;
-
-  /* Context from XML stream */
-  svn_ra_serf__xml_parser_t *parser_ctx;
+  apr_hash_t *ps_props;
 
   /* If not-NULL, add us to this list when we're done. */
   svn_ra_serf__list_t **done_list;
 
   svn_ra_serf__list_t done_item;
+
+} propfind_context_t;
+
+
+#define D_ "DAV:"
+#define S_ SVN_XML_NAMESPACE
+static const svn_ra_serf__xml_transition_t propfind_ttable[] = {
+  { INITIAL, D_, "multistatus", MULTISTATUS,
+    FALSE, { NULL }, TRUE },
+
+  { MULTISTATUS, D_, "response", RESPONSE,
+    FALSE, { NULL }, FALSE },
+
+  { RESPONSE, D_, "href", HREF,
+    TRUE, { NULL }, TRUE },
+
+  { RESPONSE, D_, "propstat", PROPSTAT,
+    FALSE, { NULL }, TRUE },
+
+  { PROPSTAT, D_, "status", STATUS,
+    TRUE, { NULL }, TRUE },
+
+  { PROPSTAT, D_, "prop", PROP,
+    FALSE, { NULL }, FALSE },
+
+  { PROP, "*", "*", PROPVAL,
+    TRUE, { "?V:encoding", NULL }, TRUE },
+
+  { PROPVAL, D_, "collection", COLLECTION,
+    FALSE, { NULL }, TRUE },
+
+  { PROPVAL, D_, "href", HREF_VALUE,
+    TRUE, { NULL }, TRUE },
+
+  { 0 }
 };
 
 
+/* Return the HTTP status code contained in STATUS_LINE, or 0 if
+   there's a problem parsing it. */
+static int parse_status_code(const char *status_line)
+{
+  /* STATUS_LINE should be of form: "HTTP/1.1 200 OK" */
+  if (status_line[0] == 'H' &&
+      status_line[1] == 'T' &&
+      status_line[2] == 'T' &&
+      status_line[3] == 'P' &&
+      status_line[4] == '/' &&
+      (status_line[5] >= '0' && status_line[5] <= '9') &&
+      status_line[6] == '.' &&
+      (status_line[7] >= '0' && status_line[7] <= '9') &&
+      status_line[8] == ' ')
+    {
+      char *reason;
+
+      return apr_strtoi64(status_line + 8, &reason, 10);
+    }
+  return 0;
+}
+
+
+/* Conforms to svn_ra_serf__path_rev_walker_t  */
+static svn_error_t *
+copy_into_ret_props(void *baton,
+                    const char *path, apr_ssize_t path_len,
+                    const char *ns, apr_ssize_t ns_len,
+                    const char *name, apr_ssize_t name_len,
+                    const svn_string_t *val,
+                    apr_pool_t *pool)
+{
+  propfind_context_t *ctx = baton;
+
+  svn_ra_serf__set_ver_prop(ctx->ret_props, path, ctx->rev, ns, name,
+                            val, ctx->pool);
+  return SVN_NO_ERROR;
+}
+
+
+/* Conforms to svn_ra_serf__xml_opened_t  */
+static svn_error_t *
+propfind_opened(svn_ra_serf__xml_estate_t *xes,
+                void *baton,
+                int entered_state,
+                const svn_ra_serf__dav_props_t *tag,
+                apr_pool_t *scratch_pool)
+{
+  propfind_context_t *ctx = baton;
+
+  if (entered_state == PROPVAL)
+    {
+      svn_ra_serf__xml_note(xes, PROPVAL, "ns", tag->namespace);
+      svn_ra_serf__xml_note(xes, PROPVAL, "name", tag->name);
+    }
+  else if (entered_state == PROPSTAT)
+    {
+      ctx->ps_props = apr_hash_make(ctx->pool);
+    }
+
+  return SVN_NO_ERROR;
+}
+
+
+/* Conforms to svn_ra_serf__xml_closed_t  */
+static svn_error_t *
+propfind_closed(svn_ra_serf__xml_estate_t *xes,
+                void *baton,
+                int leaving_state,
+                const svn_string_t *cdata,
+                apr_hash_t *attrs,
+                apr_pool_t *scratch_pool)
+{
+  propfind_context_t *ctx = baton;
+
+  if (leaving_state == MULTISTATUS)
+    {
+      /* We've gathered all the data from the reponse. Add this item
+         onto the "done list". External callers will then know this
+         request has been completed (tho stray response bytes may still
+         arrive).  */
+      if (ctx->done_list)
+        {
+          ctx->done_item.data = ctx->handler;
+          ctx->done_item.next = *ctx->done_list;
+          *ctx->done_list = &ctx->done_item;
+        }
+    }
+  else if (leaving_state == HREF)
+    {
+      const char *path;
+      const svn_string_t *val_str;
+
+      if (strcmp(ctx->depth, "1") == 0)
+        path = svn_urlpath__canonicalize(cdata->data, scratch_pool);
+      else
+        path = ctx->path;
+
+      svn_ra_serf__xml_note(xes, RESPONSE, "path", path);
+
+      /* Copy the value into the right pool, then save the HREF.  */
+      val_str = svn_string_dup(cdata, ctx->pool);
+      svn_ra_serf__set_ver_prop(ctx->ret_props,
+                                path, ctx->rev, D_, "href", val_str,
+                                ctx->pool);
+    }
+  else if (leaving_state == COLLECTION)
+    {
+      svn_ra_serf__xml_note(xes, PROPVAL, "altvalue", "collection");
+    }
+  else if (leaving_state == HREF_VALUE)
+    {
+      svn_ra_serf__xml_note(xes, PROPVAL, "altvalue", cdata->data);
+    }
+  else if (leaving_state == STATUS)
+    {
+      /* Parse the status field, and remember if this is a property
+         that we wish to ignore.  (Typically, if it's not a 200, the
+         status will be 404 to indicate that a property we
+         specifically requested from the server doesn't exist.)  */
+      int status = parse_status_code(cdata->data);
+      if (status != 200)
+        svn_ra_serf__xml_note(xes, PROPSTAT, "ignore-prop", "*");
+    }
+  else if (leaving_state == PROPVAL)
+    {
+      const char *encoding = apr_hash_get(attrs, "V:encoding",
+                                          APR_HASH_KEY_STRING);
+      const svn_string_t *val_str;
+      apr_hash_t *gathered;
+      const char *path;
+      const char *ns;
+      const char *name;
+      const char *altvalue;
+
+      if (encoding)
+        {
+          if (strcmp(encoding, "base64") != 0)
+            return svn_error_createf(SVN_ERR_RA_DAV_MALFORMED_DATA,
+                                     NULL,
+                                     _("Got unrecognized encoding '%s'"),
+                                     encoding);
+
+          /* Decode into the right pool.  */
+          val_str = svn_base64_decode_string(cdata, ctx->pool);
+        }
+      else
+        {
+          /* Copy into the right pool.  */
+          val_str = svn_string_dup(cdata, ctx->pool);
+        }
+
+      /* The current path sits on the RESPONSE state. Gather up all the
+         state from this PROPVAL to the (grandparent) RESPONSE state,
+         and grab the path from there.
+
+         Now, it would be nice if we could, at this point, know that
+         the status code for this property indicated a problem -- then
+         we could simply bail out here and ignore the property.
+         Sadly, though, we might get the status code *after* we get
+         the property value.  So we'll carry on with our processing
+         here, setting the property and value as expected.  Once we
+         know for sure the status code associate with the property,
+         we'll decide its fate.  */
+      gathered = svn_ra_serf__xml_gather_since(xes, RESPONSE);
+
+      /* These will be dup'd into CTX->POOL, as necessary.  */
+      path = apr_hash_get(gathered, "path", APR_HASH_KEY_STRING);
+      if (path == NULL)
+        path = ctx->path;
+
+      ns = apr_hash_get(attrs, "ns", APR_HASH_KEY_STRING);
+      name = apr_pstrdup(ctx->pool,
+                         apr_hash_get(attrs, "name", APR_HASH_KEY_STRING));
+
+      altvalue = apr_hash_get(attrs, "altvalue", APR_HASH_KEY_STRING);
+      if (altvalue != NULL)
+        val_str = svn_string_create(altvalue, ctx->pool);
+
+      svn_ra_serf__set_ver_prop(ctx->ps_props,
+                                path, ctx->rev, ns, name, val_str,
+                                ctx->pool);
+    }
+  else
+    {
+      apr_hash_t *gathered;
+      const char *path;
+
+      SVN_ERR_ASSERT(leaving_state == PROPSTAT);
+
+      gathered = svn_ra_serf__xml_gather_since(xes, PROPSTAT);
+
+      path = apr_hash_get(gathered, "path", APR_HASH_KEY_STRING);
+      if (path == NULL)
+        path = ctx->path;
+
+      /* If we've squirreled away a note that says we want to ignore
+         these properties, we'll do so.  Otherwise, we need to copy
+         them from the temporary hash into the ctx->ret_props hash. */
+      if (! apr_hash_get(gathered, "ignore-prop", APR_HASH_KEY_STRING))
+        {
+          SVN_ERR(svn_ra_serf__walk_all_paths(ctx->ps_props, ctx->rev,
+                                              copy_into_ret_props, ctx,
+                                              scratch_pool));
+        }
+
+      ctx->ps_props = NULL;
+    }
+
+  return SVN_NO_ERROR;
+}
+
+
 const svn_string_t *
 svn_ra_serf__get_ver_prop_string(apr_hash_t *props,
                                  const char *path,
@@ -226,197 +465,15 @@ svn_ra_serf__set_prop(apr_hash_t *props,
                             val, pool);
 }
 
-static prop_info_t *
-push_state(svn_ra_serf__xml_parser_t *parser,
-           svn_ra_serf__propfind_context_t *propfind,
-           prop_state_e state)
-{
-  svn_ra_serf__xml_push_state(parser, state);
-
-  if (state == PROPVAL)
-    {
-      prop_info_t *info;
-
-      info = apr_pcalloc(parser->state->pool, sizeof(*info));
-      info->pool = parser->state->pool;
-      info->value = svn_stringbuf_create_empty(info->pool);
-
-      parser->state->private = info;
-    }
-
-  return parser->state->private;
-}
-
-/*
- * Expat callback invoked on a start element tag for a PROPFIND response.
- */
-static svn_error_t *
-start_propfind(svn_ra_serf__xml_parser_t *parser,
-               svn_ra_serf__dav_props_t name,
-               const char **attrs,
-               apr_pool_t *scratch_pool)
-{
-  svn_ra_serf__propfind_context_t *ctx = parser->user_data;
-  prop_state_e state;
-  prop_info_t *info;
-
-  state = parser->state->current_state;
-
-  if (state == NONE && strcmp(name.name, "response") == 0)
-    {
-      svn_ra_serf__xml_push_state(parser, RESPONSE);
-    }
-  else if (state == RESPONSE && strcmp(name.name, "href") == 0)
-    {
-      info = push_state(parser, ctx, PROPVAL);
-      info->ns = name.namespace;
-      info->name = "href";
-    }
-  else if (state == RESPONSE && strcmp(name.name, "prop") == 0)
-    {
-      push_state(parser, ctx, PROP);
-    }
-  else if (state == PROP)
-    {
-      info = push_state(parser, ctx, PROPVAL);
-      info->ns = name.namespace;
-      info->name = apr_pstrdup(info->pool, name.name);
-      info->encoding = apr_pstrdup(info->pool,
-                                   svn_xml_get_attr_value("V:encoding", attrs));
-    }
-
-  return SVN_NO_ERROR;
-}
-
-/*
- * Expat callback invoked on an end element tag for a PROPFIND response.
- */
-static svn_error_t *
-end_propfind(svn_ra_serf__xml_parser_t *parser,
-             svn_ra_serf__dav_props_t name,
-             apr_pool_t *scratch_pool)
-{
-  svn_ra_serf__propfind_context_t *ctx = parser->user_data;
-  prop_state_e state;
-  prop_info_t *info;
-
-  state = parser->state->current_state;
-  info = parser->state->private;
-
-  if (state == RESPONSE && strcmp(name.name, "response") == 0)
-    {
-      svn_ra_serf__xml_pop_state(parser);
-    }
-  else if (state == PROP && strcmp(name.name, "prop") == 0)
-    {
-      svn_ra_serf__xml_pop_state(parser);
-    }
-  else if (state == PROPVAL)
-    {
-      const char *ns;
-      const char *pname;
-      const svn_string_t *val_str = NULL;
-
-      /* if we didn't see a CDATA element, we may want the tag name
-       * as long as it isn't equivalent to the property name.
-       */
-      /* ### gstein sez: I have no idea what this is about.  */
-      if (*info->value->data == '\0')
-        {
-          if (strcmp(info->name, name.name) != 0)
-            val_str = svn_string_create(name.name, ctx->pool);
-          else
-            val_str = svn_string_create_empty(ctx->pool);
-        }
-
-      if (parser->state->prev->current_state == RESPONSE &&
-          strcmp(name.name, "href") == 0)
-        {
-          if (strcmp(ctx->depth, "1") == 0)
-            {
-              ctx->current_path =
-                svn_urlpath__canonicalize(info->value->data, ctx->pool);
-            }
-          else
-            {
-              ctx->current_path = ctx->path;
-            }
-        }
-      else if (info->encoding)
-        {
-          if (strcmp(info->encoding, "base64") == 0)
-            {
-              const svn_string_t *morph;
-
-              morph = svn_stringbuf__morph_into_string(info->value);
-#ifdef SVN_DEBUG
-              info->value = NULL;  /* morph killed the stringbuf.  */
-#endif
-              val_str = svn_base64_decode_string(morph, ctx->pool);
-            }
-          else
-            {
-              return svn_error_createf(SVN_ERR_RA_DAV_MALFORMED_DATA,
-                                       NULL,
-                                       _("Got unrecognized encoding '%s'"),
-                                       info->encoding);
-            }
-        }
-
-      /* ### there may be better logic to ensure this is set above, but just
-         ### going for the easy win here.  */
-      if (val_str == NULL)
-        val_str = svn_string_create_from_buf(info->value, ctx->pool);
-
-      ns = apr_pstrdup(ctx->pool, info->ns);
-      pname = apr_pstrdup(ctx->pool, info->name);
-
-      /* set the return props and update our cache too. */
-      svn_ra_serf__set_ver_prop(ctx->ret_props,
-                                ctx->current_path, ctx->rev,
-                                ns, pname, val_str,
-                                ctx->pool);
-
-      svn_ra_serf__xml_pop_state(parser);
-    }
-
-  return SVN_NO_ERROR;
-}
-
-/*
- * Expat callback invoked on CDATA elements in a PROPFIND response.
- *
- * This callback can be called multiple times.
- */
-static svn_error_t *
-cdata_propfind(svn_ra_serf__xml_parser_t *parser,
-               const char *data,
-               apr_size_t len,
-               apr_pool_t *scratch_pool)
-{
-  svn_ra_serf__propfind_context_t *ctx = parser->user_data;
-  prop_state_e state;
-  prop_info_t *info;
-
-  UNUSED_CTX(ctx);
-
-  state = parser->state->current_state;
-  info = parser->state->private;
-
-  if (state == PROPVAL)
-    svn_stringbuf_appendbytes(info->value, data, len);
-
-  return SVN_NO_ERROR;
-}
 
 static svn_error_t *
 setup_propfind_headers(serf_bucket_t *headers,
                         void *setup_baton,
                         apr_pool_t *pool)
 {
-  svn_ra_serf__propfind_context_t *ctx = setup_baton;
+  propfind_context_t *ctx = setup_baton;
 
-  if (ctx->conn->using_compression)
+  if (ctx->sess->using_compression)
     {
       serf_bucket_headers_setn(headers, "Accept-Encoding", "gzip");
     }
@@ -438,7 +495,7 @@ create_propfind_body(serf_bucket_t **bkt
                      serf_bucket_alloc_t *alloc,
                      apr_pool_t *pool)
 {
-  svn_ra_serf__propfind_context_t *ctx = setup_baton;
+  propfind_context_t *ctx = setup_baton;
 
   serf_bucket_t *body_bkt, *tmp;
   const svn_ra_serf__dav_props_t *prop;
@@ -511,7 +568,7 @@ create_propfind_body(serf_bucket_t **bkt
 
 
 svn_error_t *
-svn_ra_serf__deliver_props(svn_ra_serf__propfind_context_t **prop_ctx,
+svn_ra_serf__deliver_props(svn_ra_serf__handler_t **propfind_handler,
                            apr_hash_t *ret_props,
                            svn_ra_serf__session_t *sess,
                            svn_ra_serf__connection_t *conn,
@@ -522,9 +579,9 @@ svn_ra_serf__deliver_props(svn_ra_serf__
                            svn_ra_serf__list_t **done_list,
                            apr_pool_t *pool)
 {
-  svn_ra_serf__propfind_context_t *new_prop_ctx;
+  propfind_context_t *new_prop_ctx;
   svn_ra_serf__handler_t *handler;
-  svn_ra_serf__xml_parser_t *parser_ctx;
+  svn_ra_serf__xml_context_t *xmlctx;
 
   new_prop_ctx = apr_pcalloc(pool, sizeof(*new_prop_ctx));
 
@@ -533,7 +590,6 @@ svn_ra_serf__deliver_props(svn_ra_serf__
   new_prop_ctx->find_props = find_props;
   new_prop_ctx->ret_props = ret_props;
   new_prop_ctx->depth = depth;
-  new_prop_ctx->done = FALSE;
   new_prop_ctx->sess = sess;
   new_prop_ctx->conn = conn;
   new_prop_ctx->rev = rev;
@@ -548,9 +604,14 @@ svn_ra_serf__deliver_props(svn_ra_serf__
       new_prop_ctx->label = NULL;
     }
 
-  handler = apr_pcalloc(pool, sizeof(*handler));
+  xmlctx = svn_ra_serf__xml_context_create(propfind_ttable,
+                                           propfind_opened,
+                                           propfind_closed,
+                                           NULL,
+                                           new_prop_ctx,
+                                           pool);
+  handler = svn_ra_serf__create_expat_handler(xmlctx, pool);
 
-  handler->handler_pool = pool;
   handler->method = "PROPFIND";
   handler->path = path;
   handler->body_delegate = create_propfind_body;
@@ -564,51 +625,28 @@ svn_ra_serf__deliver_props(svn_ra_serf__
 
   new_prop_ctx->handler = handler;
 
-  parser_ctx = apr_pcalloc(pool, sizeof(*new_prop_ctx->parser_ctx));
-  parser_ctx->pool = pool;
-  parser_ctx->user_data = new_prop_ctx;
-  parser_ctx->start = start_propfind;
-  parser_ctx->end = end_propfind;
-  parser_ctx->cdata = cdata_propfind;
-  parser_ctx->done = &new_prop_ctx->done;
-  parser_ctx->done_list = new_prop_ctx->done_list;
-  parser_ctx->done_item = &new_prop_ctx->done_item;
-
-  new_prop_ctx->parser_ctx = parser_ctx;
-
-  handler->response_handler = svn_ra_serf__handle_xml_parser;
-  handler->response_baton = parser_ctx;
-
-  /* create request */
-  svn_ra_serf__request_create(new_prop_ctx->handler);
-
-  *prop_ctx = new_prop_ctx;
+  *propfind_handler = handler;
 
   return SVN_NO_ERROR;
 }
 
-svn_boolean_t
-svn_ra_serf__propfind_is_done(svn_ra_serf__propfind_context_t *ctx)
-{
-  return ctx->done;
-}
-
 
 /*
  * This helper function will block until the PROP_CTX indicates that is done
  * or another error is returned.
  */
 svn_error_t *
-svn_ra_serf__wait_for_props(svn_ra_serf__propfind_context_t *prop_ctx,
-                            svn_ra_serf__session_t *sess,
-                            apr_pool_t *pool)
+svn_ra_serf__wait_for_props(svn_ra_serf__handler_t *handler,
+                            apr_pool_t *scratch_pool)
 {
-  svn_error_t *err, *err2;
+  svn_error_t *err;
+  svn_error_t *err2;
 
-  err = svn_ra_serf__context_run_wait(&prop_ctx->done, sess, pool);
+  err = svn_ra_serf__context_run_one(handler, scratch_pool);
 
-  err2 = svn_ra_serf__error_on_status(prop_ctx->handler->sline.code,
-                                      prop_ctx->path, NULL);
+  err2 = svn_ra_serf__error_on_status(handler->sline.code,
+                                      handler->path,
+                                      NULL);
   if (err2)
     {
       svn_error_clear(err);
@@ -632,13 +670,13 @@ svn_ra_serf__retrieve_props(apr_hash_t *
                             apr_pool_t *result_pool,
                             apr_pool_t *scratch_pool)
 {
-  svn_ra_serf__propfind_context_t *prop_ctx;
+  svn_ra_serf__handler_t *handler;
 
   *results = apr_hash_make(result_pool);
 
-  SVN_ERR(svn_ra_serf__deliver_props(&prop_ctx, *results, sess, conn, url,
+  SVN_ERR(svn_ra_serf__deliver_props(&handler, *results, sess, conn, url,
                                      rev, depth, props, NULL, result_pool));
-  SVN_ERR(svn_ra_serf__wait_for_props(prop_ctx, sess, result_pool));
+  SVN_ERR(svn_ra_serf__wait_for_props(handler, scratch_pool));
 
   return SVN_NO_ERROR;
 }

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=1360103&r1=1360102&r2=1360103&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 Wed Jul 11 10:26:19 2012
@@ -71,22 +71,11 @@ typedef struct svn_ra_serf__connection_t
   /* Our connection to a server. */
   serf_connection_t *conn;
 
-  /* The server is not Apache/mod_dav_svn (directly) and only supports
-     HTTP/1.0. Thus, we cannot send chunked requests.  */
-  svn_boolean_t http10;
-
   /* Bucket allocator for this connection. */
   serf_bucket_alloc_t *bkt_alloc;
 
-  /* Host name */
-  const char *hostname;
-
-  /* Are we using ssl */
-  svn_boolean_t using_ssl;
-  int server_cert_failures; /* Collected cert failures in chain */
-
-  /* Should we ask for compressed responses? */
-  svn_boolean_t using_compression;
+  /* Collected cert failures in chain.  */
+  int server_cert_failures;
 
   /* What was the last HTTP status code we got on this connection? */
   int last_status_code;
@@ -98,11 +87,11 @@ typedef struct svn_ra_serf__connection_t
 
   svn_ra_serf__session_t *session;
 
-  /* user agent string */
-  const char *useragent;
-
 } svn_ra_serf__connection_t;
 
+/** Max. number of connctions we'll open to the server. */
+#define MAX_NR_OF_CONNS 4
+
 /*
  * The master serf RA session.
  *
@@ -121,8 +110,11 @@ struct svn_ra_serf__session_t {
   /* Should we ask for compressed responses? */
   svn_boolean_t using_compression;
 
+  /* The user agent string */
+  const char *useragent;
+
   /* The current connection */
-  svn_ra_serf__connection_t **conns;
+  svn_ra_serf__connection_t *conns[MAX_NR_OF_CONNS];
   int num_conns;
   int cur_conn;
 
@@ -134,6 +126,10 @@ struct svn_ra_serf__session_t {
   apr_uri_t repos_root;
   const char *repos_root_str;
 
+  /* The server is not Apache/mod_dav_svn (directly) and only supports
+     HTTP/1.0. Thus, we cannot send chunked requests.  */
+  svn_boolean_t http10;
+
   /* Our Version-Controlled-Configuration; may be NULL until we know it. */
   const char *vcc_url;
 
@@ -186,7 +182,7 @@ struct svn_ra_serf__session_t {
   const char *uuid;
 
   /* Connection timeout value */
-  long timeout;
+  apr_short_interval_time_t timeout;
 
   /* HTTPv1 flags */
   svn_tristate_t supports_deadprop_count;
@@ -286,6 +282,13 @@ static const svn_ra_serf__dav_props_t ch
   { NULL }
 };
 
+static const svn_ra_serf__dav_props_t type_and_checksum_props[] =
+{
+  { "DAV:", "resourcetype" },
+  { SVN_DAV_PROP_NS_DAV, "sha1-checksum" },
+  { NULL }
+};
+
 /* WC props compatibility with ra_neon. */
 #define SVN_RA_SERF__WC_CHECKED_IN_URL SVN_PROP_WC_PREFIX "ra_dav:version-url"
 
@@ -659,13 +662,18 @@ typedef svn_error_t *
                              apr_pool_t *scratch_pool);
 
 
-/* ### TBD  */
+/* Called for all states that are not using the builtin cdata collection.
+   This callback is (only) appropriate for unbounded-size cdata content.
+
+   CURRENT_STATE may be used to decide what to do with the data.
+
+   Temporary allocations may be made in SCRATCH_POOL.  */
 typedef svn_error_t *
 (*svn_ra_serf__xml_cdata_t)(svn_ra_serf__xml_estate_t *xes,
                             void *baton,
                             int current_state,
                             const char *data,
-                            apr_size_t *len,
+                            apr_size_t len,
                             apr_pool_t *scratch_pool);
 
 
@@ -708,7 +716,22 @@ typedef struct svn_ra_serf__xml_transiti
 } svn_ra_serf__xml_transition_t;
 
 
-/* ### docco  */
+/* Construct an XML parsing context, based on the TTABLE transition table.
+   As content is parsed, the CLOSED_CB callback will be invoked according
+   to the definition in the table.
+
+   If OPENED_CB is not NULL, then it will be invoked for *every* tag-open
+   event. The callback will need to use the ENTERED_STATE and TAG parameters
+   to decide what it would like to do.
+
+   If CDATA_CB is not NULL, then it will be called for all cdata that is
+   not be automatically collected (based on the transition table record's
+   COLLECT_CDATA flag). It will be called in every state, so the callback
+   must examine the CURRENT_STATE parameter to decide what to do.
+
+   The same BATON value will be passed to all three callbacks.
+
+   The context will be created within RESULT_POOL.  */
 svn_ra_serf__xml_context_t *
 svn_ra_serf__xml_context_create(
   const svn_ra_serf__xml_transition_t *ttable,
@@ -718,6 +741,10 @@ svn_ra_serf__xml_context_create(
   void *baton,
   apr_pool_t *result_pool);
 
+/* Destroy all subpools for this structure. */
+void
+svn_ra_serf__xml_context_destroy(
+  svn_ra_serf__xml_context_t *xmlctx);
 
 /* Construct a handler with the response function/baton set up to parse
    a response body using the given XML context. The handler and its
@@ -729,8 +756,8 @@ svn_ra_serf__create_expat_handler(svn_ra
                                   apr_pool_t *result_pool);
 
 
-/* Allocated within XES->STATE_POOL. Changes are not allowd. Make a deep
-   copy, as appropriate.
+/* Allocated within XES->STATE_POOL. Changes are not allowd (callers
+   should make a deep copy if they need to make changes).
 
    The resulting hash maps char* names to char* values.  */
 apr_hash_t *
@@ -757,7 +784,10 @@ svn_ra_serf__xml_note(svn_ra_serf__xml_e
 
 
 /* Returns XES->STATE_POOL for allocating structures that should live
-   as long as the state identified by XES.  */
+   as long as the state identified by XES.
+
+   Note: a state pool is created upon demand, so only use this function
+   when memory is required for a given state.  */
 apr_pool_t *
 svn_ra_serf__xml_state_pool(svn_ra_serf__xml_estate_t *xes);
 
@@ -894,12 +924,6 @@ svn_ra_serf__response_discard_handler(se
                                       void *baton,
                                       apr_pool_t *pool);
 
-/* Return the value of the RESPONSE's Location header if any, or NULL
- * otherwise.  All allocations will be made in POOL.
- */
-const char *
-svn_ra_serf__response_get_location(serf_bucket_t *response,
-                                   apr_pool_t *pool);
 
 /** XML helper functions. **/
 
@@ -1007,16 +1031,6 @@ svn_ra_serf__expand_ns(svn_ra_serf__dav_
 
 /** PROPFIND-related functions **/
 
-/* Opaque structure representing PROPFINDs. */
-typedef struct svn_ra_serf__propfind_context_t svn_ra_serf__propfind_context_t;
-
-/*
- * Returns a flag representing whether the PROPFIND @a ctx is completed.
- */
-svn_boolean_t
-svn_ra_serf__propfind_is_done(svn_ra_serf__propfind_context_t *ctx);
-
-
 /*
  * This function will deliver a PROP_CTX PROPFIND request in the SESS
  * serf context for the properties listed in LOOKUP_PROPS at URL for
@@ -1026,7 +1040,7 @@ svn_ra_serf__propfind_is_done(svn_ra_ser
  * expected to call svn_ra_serf__wait_for_props().
  */
 svn_error_t *
-svn_ra_serf__deliver_props(svn_ra_serf__propfind_context_t **prop_ctx,
+svn_ra_serf__deliver_props(svn_ra_serf__handler_t **propfind_handler,
                            apr_hash_t *prop_vals,
                            svn_ra_serf__session_t *sess,
                            svn_ra_serf__connection_t *conn,
@@ -1038,13 +1052,12 @@ svn_ra_serf__deliver_props(svn_ra_serf__
                            apr_pool_t *pool);
 
 /*
- * This helper function will block until the PROP_CTX indicates that is done
- * or another error is returned.
+ * This helper function will block until PROPFIND_HANDLER indicates that is
+ * done or another error is returned.
  */
 svn_error_t *
-svn_ra_serf__wait_for_props(svn_ra_serf__propfind_context_t *prop_ctx,
-                            svn_ra_serf__session_t *sess,
-                            apr_pool_t *pool);
+svn_ra_serf__wait_for_props(svn_ra_serf__handler_t *handler,
+                            apr_pool_t *scratch_pool);
 
 /* This is a blocking version of deliver_props.
 

Modified: subversion/branches/ev2-export/subversion/libsvn_ra_serf/replay.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra_serf/replay.c?rev=1360103&r1=1360102&r2=1360103&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra_serf/replay.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra_serf/replay.c Wed Jul 11 10:26:19 2012
@@ -129,7 +129,7 @@ typedef struct replay_context_t {
   svn_ra_serf__xml_parser_t *parser_ctx;
 
   /* The propfind for the revision properties of the current revision */
-  svn_ra_serf__propfind_context_t *prop_ctx;
+  svn_ra_serf__handler_t *propfind_handler;
 
 } replay_context_t;
 
@@ -188,8 +188,7 @@ start_replay(svn_ra_serf__xml_parser_t *
       push_state(parser, ctx, REPORT);
 
       /* Before we can continue, we need the revision properties. */
-      SVN_ERR_ASSERT(!ctx->prop_ctx
-                     || svn_ra_serf__propfind_is_done(ctx->prop_ctx));
+      SVN_ERR_ASSERT(!ctx->propfind_handler || ctx->propfind_handler->done);
 
       /* Create a pool for the commit editor. */
       ctx->dst_rev_pool = svn_pool_create(ctx->src_rev_pool);
@@ -781,7 +780,7 @@ svn_ra_serf__replay_range(svn_ra_session
               replay_ctx->revprop_rev = rev;
             }
 
-          SVN_ERR(svn_ra_serf__deliver_props(&replay_ctx->prop_ctx,
+          SVN_ERR(svn_ra_serf__deliver_props(&replay_ctx->propfind_handler,
                                              replay_ctx->revs_props, session,
                                              session->conns[0],
                                              replay_ctx->revprop_target,
@@ -790,6 +789,9 @@ svn_ra_serf__replay_range(svn_ra_session
                                              NULL,
                                              replay_ctx->src_rev_pool));
 
+          /* Spin up the serf request for the PROPFIND.  */
+          svn_ra_serf__request_create(replay_ctx->propfind_handler);
+
           /* Send the replay report request. */
           handler = apr_pcalloc(replay_ctx->src_rev_pool, sizeof(*handler));
 

Modified: subversion/branches/ev2-export/subversion/libsvn_ra_serf/serf.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra_serf/serf.c?rev=1360103&r1=1360102&r2=1360103&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra_serf/serf.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra_serf/serf.c Wed Jul 11 10:26:19 2012
@@ -270,6 +270,11 @@ load_config(svn_ra_serf__session_t *sess
   else
     session->timeout = apr_time_from_sec(DEFAULT_HTTP_TIMEOUT);
 
+  if (session->timeout < 0) /* Always true for DEFAULT_HTTP_TIMEOUT */
+    session->timeout = apr_time_from_sec(600); /* 10 min */
+
+  SVN_ERR_ASSERT(session->timeout > 0);
+
   /* Convert the proxy port value, if any. */
   if (port_str)
     {
@@ -392,33 +397,27 @@ svn_ra_serf__open(svn_ra_session_t *sess
 
   serf_sess->capabilities = apr_hash_make(serf_sess->pool);
 
-  SVN_ERR(load_config(serf_sess, config, serf_sess->pool));
-
+  serf_sess->http10 = TRUE;  /* until we confirm HTTP/1.1  */
+  serf_sess->http10 = FALSE; /* ### don't change behavior yet  */
 
-  serf_sess->conns = apr_palloc(serf_sess->pool, sizeof(*serf_sess->conns) * 4);
+  SVN_ERR(load_config(serf_sess, config, serf_sess->pool));
 
   serf_sess->conns[0] = apr_pcalloc(serf_sess->pool,
                                     sizeof(*serf_sess->conns[0]));
-  serf_sess->conns[0]->http10 = TRUE;  /* until we confirm HTTP/1.1  */
-  serf_sess->conns[0]->http10 = FALSE; /* ### don't change behavior yet  */
   serf_sess->conns[0]->bkt_alloc =
           serf_bucket_allocator_create(serf_sess->pool, NULL, NULL);
   serf_sess->conns[0]->session = serf_sess;
   serf_sess->conns[0]->last_status_code = -1;
 
-  serf_sess->conns[0]->using_ssl = serf_sess->using_ssl;
-  serf_sess->conns[0]->using_compression = serf_sess->using_compression;
-  serf_sess->conns[0]->hostname = url.hostname;
-
   /* create the user agent string */
   if (callbacks->get_client_string)
     callbacks->get_client_string(callback_baton, &client_string, pool);
 
   if (client_string)
-    serf_sess->conns[0]->useragent = apr_pstrcat(pool, USER_AGENT, "/",
-                                                 client_string, (char *)NULL);
+    serf_sess->useragent = apr_pstrcat(pool, USER_AGENT, "/",
+                                       client_string, (char *)NULL);
   else
-    serf_sess->conns[0]->useragent = USER_AGENT;
+    serf_sess->useragent = USER_AGENT;
 
   /* go ahead and tell serf about the connection. */
   status =