You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ph...@apache.org on 2014/02/18 23:49:38 UTC

svn commit: r1569549 - /subversion/trunk/subversion/libsvn_fs_fs/transaction.c

Author: philip
Date: Tue Feb 18 22:49:38 2014
New Revision: 1569549

URL: http://svn.apache.org/r1569549
Log:
The txn-list-lock protects the shared txn structures but not the
protorev file so the txn-list-lock can be released before doing the
disk IO to open, and seek to the end of, the protorev file.  This
reduces contention for the txn-list-lock.

* subversion/libsvn_fs_fs/transaction.c
  (unlock_proto_rev_list_locked): Remove.
  (struct get_writable_proto_rev_baton): Remove file member.
  (get_writable_proto_rev_body): Move open/seek from here ...
  (get_writable_proto_rev): ... to here.

Modified:
    subversion/trunk/subversion/libsvn_fs_fs/transaction.c

Modified: subversion/trunk/subversion/libsvn_fs_fs/transaction.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_fs/transaction.c?rev=1569549&r1=1569548&r2=1569549&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_fs/transaction.c (original)
+++ subversion/trunk/subversion/libsvn_fs_fs/transaction.c Tue Feb 18 22:49:38 2014
@@ -317,26 +317,10 @@ unlock_proto_rev(svn_fs_t *fs,
   return with_txnlist_lock(fs, unlock_proto_rev_body, &b, pool);
 }
 
-/* Same as unlock_proto_rev(), but requires that the transaction list
-   lock is already held. */
-static svn_error_t *
-unlock_proto_rev_list_locked(svn_fs_t *fs,
-                             const svn_fs_fs__id_part_t *txn_id,
-                             void *lockcookie,
-                             apr_pool_t *pool)
-{
-  struct unlock_proto_rev_baton b;
-
-  b.txn_id = *txn_id;
-  b.lockcookie = lockcookie;
-  return unlock_proto_rev_body(fs, &b, pool);
-}
-
 /* A structure used by get_writable_proto_rev() and
    get_writable_proto_rev_body(), which see. */
 struct get_writable_proto_rev_baton
 {
-  apr_file_t **file;
   void **lockcookie;
   svn_fs_fs__id_part_t txn_id;
 };
@@ -346,9 +330,7 @@ static svn_error_t *
 get_writable_proto_rev_body(svn_fs_t *fs, const void *baton, apr_pool_t *pool)
 {
   const struct get_writable_proto_rev_baton *b = baton;
-  apr_file_t **file = b->file;
   void **lockcookie = b->lockcookie;
-  svn_error_t *err;
   fs_fs_shared_txn_data_t *txn = get_shared_txn(fs, &b->txn_id, TRUE);
 
   /* First, ensure that no thread in this process (including this one)
@@ -410,10 +392,37 @@ get_writable_proto_rev_body(svn_fs_t *fs
   /* We've successfully locked the transaction; mark it as such. */
   txn->being_written = TRUE;
 
+  return SVN_NO_ERROR;
+}
+
+/* Get a handle to the prototype revision file for transaction TXN_ID in
+   filesystem FS, and lock it for writing.  Return FILE, a file handle
+   positioned at the end of the file, and LOCKCOOKIE, a cookie that
+   should be passed to unlock_proto_rev() to unlock the file once FILE
+   has been closed.
+
+   If the prototype revision file is already locked, return error
+   SVN_ERR_FS_REP_BEING_WRITTEN.
+
+   Perform all allocations in POOL. */
+static svn_error_t *
+get_writable_proto_rev(apr_file_t **file,
+                       void **lockcookie,
+                       svn_fs_t *fs,
+                       const svn_fs_fs__id_part_t *txn_id,
+                       apr_pool_t *pool)
+{
+  struct get_writable_proto_rev_baton b;
+  svn_error_t *err;
+
+  b.lockcookie = lockcookie;
+  b.txn_id = *txn_id;
+
+  SVN_ERR(with_txnlist_lock(fs, get_writable_proto_rev_body, &b, pool));
 
   /* Now open the prototype revision file and seek to the end. */
   err = svn_io_file_open(file,
-                         svn_fs_fs__path_txn_proto_rev(fs, &b->txn_id, pool),
+                         svn_fs_fs__path_txn_proto_rev(fs, txn_id, pool),
                          APR_READ | APR_WRITE | APR_BUFFERED, APR_OS_DEFAULT,
                          pool);
 
@@ -434,7 +443,7 @@ get_writable_proto_rev_body(svn_fs_t *fs
     {
       err = svn_error_compose_create(
               err,
-              unlock_proto_rev_list_locked(fs, &b->txn_id, *lockcookie, pool));
+              unlock_proto_rev(fs, txn_id, *lockcookie, pool));
 
       *lockcookie = NULL;
     }
@@ -442,32 +451,6 @@ get_writable_proto_rev_body(svn_fs_t *fs
   return svn_error_trace(err);
 }
 
-/* Get a handle to the prototype revision file for transaction TXN_ID in
-   filesystem FS, and lock it for writing.  Return FILE, a file handle
-   positioned at the end of the file, and LOCKCOOKIE, a cookie that
-   should be passed to unlock_proto_rev() to unlock the file once FILE
-   has been closed.
-
-   If the prototype revision file is already locked, return error
-   SVN_ERR_FS_REP_BEING_WRITTEN.
-
-   Perform all allocations in POOL. */
-static svn_error_t *
-get_writable_proto_rev(apr_file_t **file,
-                       void **lockcookie,
-                       svn_fs_t *fs,
-                       const svn_fs_fs__id_part_t *txn_id,
-                       apr_pool_t *pool)
-{
-  struct get_writable_proto_rev_baton b;
-
-  b.file = file;
-  b.lockcookie = lockcookie;
-  b.txn_id = *txn_id;
-
-  return with_txnlist_lock(fs, get_writable_proto_rev_body, &b, pool);
-}
-
 /* Callback used in the implementation of purge_shared_txn(). */
 static svn_error_t *
 purge_shared_txn_body(svn_fs_t *fs, const void *baton, apr_pool_t *pool)