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 2013/12/27 14:23:02 UTC

svn commit: r1553671 - in /subversion/trunk/subversion: libsvn_client/commit_util.c libsvn_ra_serf/commit.c

Author: rhuijben
Date: Fri Dec 27 13:23:01 2013
New Revision: 1553671

URL: http://svn.apache.org/r1553671
Log:
For issue #4172, limit the amount of temporary files open at the same time
while committing in general and while using libsvn_ra_serf in particular.

* subversion/libsvn_client/commit_util.c
  (file_mod_t): Store per file pool, to allow destroying earlier.
  (do_item_commit): Create per file subpool. Store or close pool.
  (svn_client__do_commit): Destroy file pools as soon as we are done
    with the file.

* subversion/libsvn_ra_serf/commit.c
  (svndiff_stream_write): Remove function.
  (delayed_commit_stream_open): New function.
  (apply_textdelta): Open a lazy stream instead of a tempfile.
  (close_file): Check for a backing file instead of the stream.

Modified:
    subversion/trunk/subversion/libsvn_client/commit_util.c
    subversion/trunk/subversion/libsvn_ra_serf/commit.c

Modified: subversion/trunk/subversion/libsvn_client/commit_util.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/commit_util.c?rev=1553671&r1=1553670&r2=1553671&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/commit_util.c (original)
+++ subversion/trunk/subversion/libsvn_client/commit_util.c Fri Dec 27 13:23:01 2013
@@ -1494,6 +1494,7 @@ struct file_mod_t
 {
   const svn_client_commit_item3_t *item;
   void *file_baton;
+  apr_pool_t *file_pool;
 };
 
 
@@ -1559,6 +1560,9 @@ do_item_commit(void **dir_baton,
   else
     file_pool = pool;
 
+  /* Subpools are cheap, but memory isn't */
+  file_pool = svn_pool_create(file_pool); 
+
   /* Call the cancellation function. */
   if (ctx->cancel_func)
     SVN_ERR(ctx->cancel_func(ctx->cancel_baton));
@@ -1808,6 +1812,7 @@ do_item_commit(void **dir_baton,
       /* Add this file mod to the FILE_MODS hash. */
       mod->item = item;
       mod->file_baton = file_baton;
+      mod->file_pool = file_pool;
       svn_hash_sets(file_mods, item->session_relpath, mod);
     }
   else if (file_baton)
@@ -1815,7 +1820,7 @@ do_item_commit(void **dir_baton,
       /* Close any outstanding file batons that didn't get caught by
          the "has local mods" conditional above. */
       err = editor->close_file(file_baton, NULL, file_pool);
-
+      svn_pool_destroy(file_pool);
       if (err)
         goto fixup_error;
     }
@@ -1930,6 +1935,8 @@ svn_client__do_commit(const char *base_u
 
       if (sha1_checksums)
         svn_hash_sets(*sha1_checksums, item->path, new_text_base_sha1_checksum);
+
+      svn_pool_destroy(mod->file_pool);
     }
 
   svn_pool_destroy(iterpool);

Modified: subversion/trunk/subversion/libsvn_ra_serf/commit.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_serf/commit.c?rev=1553671&r1=1553670&r2=1553671&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_ra_serf/commit.c (original)
+++ subversion/trunk/subversion/libsvn_ra_serf/commit.c Fri Dec 27 13:23:01 2013
@@ -1192,24 +1192,6 @@ setup_delete_headers(serf_bucket_t *head
   return SVN_NO_ERROR;
 }
 
-/* Helper function to write the svndiff stream to temporary file. */
-static svn_error_t *
-svndiff_stream_write(void *file_baton,
-                     const char *data,
-                     apr_size_t *len)
-{
-  file_context_t *ctx = file_baton;
-  apr_status_t status;
-
-  status = apr_file_write_full(ctx->svndiff, data, *len, NULL);
-  if (status)
-      return svn_error_wrap_apr(status, _("Failed writing updated file"));
-
-  return SVN_NO_ERROR;
-}
-
-
-
 /* POST against 'me' resource handlers. */
 
 /* Implements svn_ra_serf__request_body_delegate_t */
@@ -1996,6 +1978,23 @@ open_file(const char *path,
   return SVN_NO_ERROR;
 }
 
+/* Implements svn_stream_lazyopen_func_t for apply_textdelta */
+static svn_error_t *
+delayed_commit_stream_open(svn_stream_t **stream,
+                           void *baton,
+                           apr_pool_t *result_pool,
+                           apr_pool_t *scratch_pool)
+{
+  file_context_t *file_ctx = baton;
+
+  SVN_ERR(svn_io_open_unique_file3(&file_ctx->svndiff, NULL, NULL,
+                                   svn_io_file_del_on_pool_cleanup,
+                                   file_ctx->pool, scratch_pool));
+
+  *stream = svn_stream_from_aprfile2(file_ctx->svndiff, TRUE, result_pool);
+  return SVN_NO_ERROR;
+}
+
 static svn_error_t *
 apply_textdelta(void *file_baton,
                 const char *base_checksum,
@@ -2018,12 +2017,8 @@ apply_textdelta(void *file_baton,
    * avoid too many simultaneously open files.
    */
 
-  SVN_ERR(svn_io_open_unique_file3(&ctx->svndiff, NULL, NULL,
-                                   svn_io_file_del_on_pool_cleanup,
-                                   ctx->pool, pool));
-
-  ctx->stream = svn_stream_create(ctx, pool);
-  svn_stream_set_write(ctx->stream, svndiff_stream_write);
+  ctx->stream = svn_stream_lazyopen_create(delayed_commit_stream_open,
+                                           ctx, FALSE, ctx->pool);
 
   svn_txdelta_to_svndiff3(handler, handler_baton, ctx->stream, 0,
                           SVN_DELTA_COMPRESSION_LEVEL_DEFAULT, pool);
@@ -2085,11 +2080,11 @@ close_file(void *file_baton,
   /* If we got no stream of changes, but this is an added-without-history
    * file, make a note that we'll be PUTting a zero-byte file to the server.
    */
-  if ((!ctx->stream) && ctx->added && (!ctx->copy_path))
+  if ((!ctx->svndiff) && ctx->added && (!ctx->copy_path))
     put_empty_file = TRUE;
 
   /* If we had a stream of changes, push them to the server... */
-  if (ctx->stream || put_empty_file)
+  if (ctx->svndiff || put_empty_file)
     {
       svn_ra_serf__handler_t *handler;
       int expected_result;