You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by rh...@apache.org on 2015/01/25 15:21:53 UTC

svn commit: r1654658 - /subversion/trunk/subversion/libsvn_ra_serf/replay.c

Author: rhuijben
Date: Sun Jan 25 14:21:53 2015
New Revision: 1654658

URL: http://svn.apache.org/r1654658
Log:
In ra_serf's replay code: avoid some unneeded complexity for code that
can just be called from the done delegate.

* subversion/libsvn_ra_serf/replay.c
  (ra_serf_list_t): Remove struct/typedef.
  (revision_report_t): Remove linked list.
  (replay_done): Move function to its only user.
  (svn_ra_serf__replay): Remove unneeded initialization.

  (replay_done): Move function here. Handle done logic from here.
  (svn_ra_serf__replay_range): Rename pool to scratch pool and move more
    data to per revision pools.

Modified:
    subversion/trunk/subversion/libsvn_ra_serf/replay.c

Modified: subversion/trunk/subversion/libsvn_ra_serf/replay.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_serf/replay.c?rev=1654658&r1=1654657&r2=1654658&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_ra_serf/replay.c (original)
+++ subversion/trunk/subversion/libsvn_ra_serf/replay.c Sun Jan 25 14:21:53 2015
@@ -112,14 +112,6 @@ static const svn_ra_serf__xml_transition
   { 0 }
 };
 
-/*
- * An incredibly simple list.
- */
-typedef struct ra_serf_list_t {
-  void *data;
-  struct ra_serf_list_t *next;
-} svn_ra_serf__list_t;
-
 /* Per directory/file state */
 typedef struct replay_node_t {
   apr_pool_t *pool; /* pool allocating this node's data */
@@ -141,8 +133,7 @@ typedef struct revision_report_t {
   /* Are we done fetching this file?
      Handles book-keeping in multi-report case */
   svn_boolean_t *done;
-  svn_ra_serf__list_t **done_list;
-  svn_ra_serf__list_t done_item;
+  int *replay_reports; /* NULL or number of outstanding reports */
 
   /* callback to get an editor */
   svn_ra_replay_revstart_callback_t revstart_func;
@@ -173,7 +164,7 @@ typedef struct revision_report_t {
 
   /* Handlers for the PROPFIND and REPORT for the current revision. */
   svn_ra_serf__handler_t *propfind_handler;
-  svn_ra_serf__handler_t *report_handler;
+  svn_ra_serf__handler_t *report_handler; /* For done handler */
 
 } revision_report_t;
 
@@ -478,29 +469,6 @@ replay_cdata(svn_ra_serf__xml_estate_t *
   return SVN_NO_ERROR;
 }
 
-/* Conforms to svn_ra_serf__response_done_delegate_t  */
-static svn_error_t *
-replay_done(serf_request_t *request,
-            void *baton,
-            apr_pool_t *scratch_pool)
-{
-  struct revision_report_t *ctx = baton;
-  svn_ra_serf__handler_t *handler = ctx->report_handler;
-
-  if (handler->server_error)
-    return svn_ra_serf__server_error_create(handler, scratch_pool);
-  else if (handler->sline.code != 200)
-    return svn_error_trace(svn_ra_serf__unexpected_status(handler));
-
-  *ctx->done = TRUE; /* Breaks out svn_ra_serf__context_run_wait */
-
-  ctx->done_item.data = ctx;
-  ctx->done_item.next = *ctx->done_list;
-  *ctx->done_list = &ctx->done_item;
-
-  return SVN_NO_ERROR;
-}
-
 /* Implements svn_ra_serf__request_body_delegate_t */
 static svn_error_t *
 create_replay_body(serf_bucket_t **bkt,
@@ -596,8 +564,6 @@ svn_ra_serf__replay(svn_ra_session_t *ra
 
   /* Not setting up done handler as we don't use a global context */
 
-  ctx.report_handler = handler; /* unused */
-
   SVN_ERR(svn_ra_serf__context_run_one(handler, scratch_pool));
 
   return svn_error_trace(
@@ -637,6 +603,33 @@ svn_ra_serf__replay(svn_ra_session_t *ra
  */
 #define MAX_OUTSTANDING_REQUESTS 50
 
+/* Implements svn_ra_serf__response_done_delegate_t for svn_ra_serf__replay_range */
+static svn_error_t *
+replay_done(serf_request_t *request,
+            void *baton,
+            apr_pool_t *scratch_pool)
+{
+  struct revision_report_t *ctx = baton;
+  svn_ra_serf__handler_t *handler = ctx->report_handler;
+
+  if (handler->server_error)
+    return svn_ra_serf__server_error_create(handler, scratch_pool);
+  else if (handler->sline.code != 200)
+    return svn_error_trace(svn_ra_serf__unexpected_status(handler));
+
+  *ctx->done = TRUE; /* Breaks out svn_ra_serf__context_run_wait */
+
+  /* Are re replaying multiple revisions? */
+  if (ctx->replay_reports)
+    {
+      (*ctx->replay_reports)--;
+    }
+
+  svn_pool_destroy(ctx->pool); /* Destroys handler and request! */
+
+  return SVN_NO_ERROR;
+}
+
 svn_error_t *
 svn_ra_serf__replay_range(svn_ra_session_t *ra_session,
                           svn_revnum_t start_revision,
@@ -646,7 +639,7 @@ svn_ra_serf__replay_range(svn_ra_session
                           svn_ra_replay_revstart_callback_t revstart_func,
                           svn_ra_replay_revfinish_callback_t revfinish_func,
                           void *replay_baton,
-                          apr_pool_t *pool)
+                          apr_pool_t *scratch_pool)
 {
   svn_ra_serf__session_t *session = ra_session->priv;
   svn_revnum_t rev = start_revision;
@@ -654,9 +647,9 @@ svn_ra_serf__replay_range(svn_ra_session
   int active_reports = 0;
   const char *include_path;
   svn_boolean_t done;
-  svn_ra_serf__list_t *done_reports = NULL;
 
-  SVN_ERR(svn_ra_serf__report_resource(&report_target, session, NULL, pool));
+  SVN_ERR(svn_ra_serf__report_resource(&report_target, session, NULL,
+                                       scratch_pool));
 
   /* Prior to 1.8, mod_dav_svn expect to get replay REPORT requests
      aimed at the session URL.  But that's incorrect -- these reports
@@ -680,7 +673,7 @@ svn_ra_serf__replay_range(svn_ra_session
       SVN_ERR(svn_ra_serf__get_relative_path(&include_path,
                                              session->session_url.path,
                                              session, session->conns[0],
-                                             pool));
+                                             scratch_pool));
     }
   else
     {
@@ -698,30 +691,29 @@ svn_ra_serf__replay_range(svn_ra_session
         {
           struct revision_report_t *rev_ctx;
           svn_ra_serf__handler_t *handler;
-          apr_pool_t *ctx_pool = svn_pool_create(pool);
+          apr_pool_t *rev_pool = svn_pool_create(scratch_pool);
           svn_ra_serf__xml_context_t *xmlctx;
           const char *replay_target;
 
-          rev_ctx = apr_pcalloc(ctx_pool, sizeof(*rev_ctx));
-          rev_ctx->pool = ctx_pool;
+          rev_ctx = apr_pcalloc(rev_pool, sizeof(*rev_ctx));
+          rev_ctx->pool = rev_pool;
           rev_ctx->revstart_func = revstart_func;
           rev_ctx->revfinish_func = revfinish_func;
           rev_ctx->replay_baton = replay_baton;
           rev_ctx->done = &done;
-          rev_ctx->done_list = &done_reports;
+          rev_ctx->replay_reports = &active_reports;
           rev_ctx->include_path = include_path;
           rev_ctx->revision = rev;
           rev_ctx->low_water_mark = low_water_mark;
           rev_ctx->send_deltas = send_deltas;
-          rev_ctx->done_item.data = rev_ctx;
 
           /* Request all properties of a certain revision. */
           rev_ctx->rev_props = apr_hash_make(rev_ctx->pool);
 
           if (SVN_RA_SERF__HAVE_HTTPV2_SUPPORT(session))
             {
-              rev_ctx->revprop_target = apr_psprintf(pool, "%s/%ld",
-                                                        session->rev_stub, rev);
+              rev_ctx->revprop_target = apr_psprintf(rev_pool, "%s/%ld",
+                                                     session->rev_stub, rev);
               rev_ctx->revprop_rev = SVN_INVALID_REVNUM;
             }
           else
@@ -737,7 +729,7 @@ svn_ra_serf__replay_range(svn_ra_session
                                               "0", all_props,
                                               svn_ra_serf__deliver_svn_props,
                                               rev_ctx->rev_props,
-                                              rev_ctx->pool));
+                                              rev_pool));
 
           /* Spin up the serf request for the PROPFIND.  */
           svn_ra_serf__request_create(rev_ctx->propfind_handler);
@@ -745,7 +737,7 @@ svn_ra_serf__replay_range(svn_ra_session
           /* Send the replay REPORT request. */
           if (session->supports_rev_rsrc_replay)
             {
-              replay_target = apr_psprintf(pool, "%s/%ld",
+              replay_target = apr_psprintf(rev_pool, "%s/%ld",
                                            session->rev_stub, rev);
             }
           else
@@ -756,9 +748,9 @@ svn_ra_serf__replay_range(svn_ra_session
           xmlctx = svn_ra_serf__xml_context_create(replay_ttable,
                                            replay_opened, replay_closed,
                                            replay_cdata, rev_ctx,
-                                           ctx_pool);
+                                           rev_pool);
 
-          handler = svn_ra_serf__create_expat_handler(xmlctx, NULL, ctx_pool);
+          handler = svn_ra_serf__create_expat_handler(xmlctx, NULL, rev_pool);
 
           handler->method = "REPORT";
           handler->path = replay_target;
@@ -779,31 +771,11 @@ svn_ra_serf__replay_range(svn_ra_session
 
       /* Run the serf loop. */
       done = FALSE;
-      SVN_ERR(svn_ra_serf__context_run_wait(&done, session, pool));
+      SVN_ERR(svn_ra_serf__context_run_wait(&done, session, scratch_pool));
 
-      /* Substract the number of completely handled responses from our
-         total nr. of open requests', so we'll know when to stop this loop.
-         Since the message is completely handled, we can destroy its pool. */
-      {
-        svn_ra_serf__list_t *done_list;
-
-        done_list = done_reports;
-
-        done_reports = NULL;
-
-        while (done_list)
-          {
-            revision_report_t *ctx = (revision_report_t *)done_list->data;
-            svn_ra_serf__handler_t *done_handler = ctx->report_handler;
-
-            done_list = done_list->next;
-            SVN_ERR(svn_ra_serf__error_on_status(done_handler->sline,
-                                                 done_handler->path,
-                                                 done_handler->location));
-            svn_pool_clear(ctx->pool);
-            active_reports--;
-          }
-      }
+      /* The done handler of reports decrements active_reports when a report
+         is done. This same handler reports (fatal) report errors, so we can
+         just loop here. */
     }
 
   return SVN_NO_ERROR;