Author: stefan2
Date: Sun Mar 16 23:09:45 2014
New Revision: 1578176

URL: http://svn.apache.org/r1578176
Log:
Model the FSFS pack lock similarly to our other file based locks in FSFS.
This gives us proper mutex functionality should multiple threads try to
pack the same repo at the same time.

* subversion/libsvn_fs_fs/fs.h
  (fs_fs_shared_data_t): Add a thread mutex alongside the file lock.

* subversion/libsvn_fs_fs/fs.c
  (fs_serialized_init): Initialize the new mutex.

* subversion/libsvn_fs_fs/fs_fs.h
  (svn_fs_fs__get_lock_on_filesystem): Privatize again.
  (svn_fs_fs__with_pack_lock): New lock handling function similar
                               to what we do for the other locks.

* subversion/libsvn_fs_fs/fs_fs.c
  (path_pack_lock): New utility function.
  (svn_fs_fs__get_lock_on_filesystem): Rename back to ...
  (get_lock_on_filesystem): ... this again.
  (with_some_lock_file): Update caller.
  (svn_fs_fs__with_pack_lock): Implement the new lock function.

* subversion/libsvn_fs_fs/pack.c
  (svn_fs_fs__pack): Use the new pack lock handling function.

Suggested by: ivan

Modified:
    subversion/trunk/subversion/libsvn_fs_fs/fs.c
    subversion/trunk/subversion/libsvn_fs_fs/fs.h
    subversion/trunk/subversion/libsvn_fs_fs/fs_fs.c
    subversion/trunk/subversion/libsvn_fs_fs/fs_fs.h
    subversion/trunk/subversion/libsvn_fs_fs/pack.c

Modified: subversion/trunk/subversion/libsvn_fs_fs/fs.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_fs/fs.c?rev=1578176&r1=1578175&r2=1578176&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_fs/fs.c (original)
+++ subversion/trunk/subversion/libsvn_fs_fs/fs.c Sun Mar 16 23:09:45 2014
@@ -99,6 +99,10 @@ fs_serialized_init(svn_fs_t *fs, apr_poo
       SVN_ERR(svn_mutex__init(&ffsd->fs_write_lock,
                               SVN_FS_FS__USE_LOCK_MUTEX, common_pool));
 
+      /* ... the pack lock ... */
+      SVN_ERR(svn_mutex__init(&ffsd->fs_pack_lock,
+                              SVN_FS_FS__USE_LOCK_MUTEX, common_pool));
+
       /* ... not to mention locking the txn-current file. */
       SVN_ERR(svn_mutex__init(&ffsd->txn_current_lock,
                               SVN_FS_FS__USE_LOCK_MUTEX, common_pool));

Modified: subversion/trunk/subversion/libsvn_fs_fs/fs.h
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_fs/fs.h?rev=1578176&r1=1578175&r2=1578176&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_fs/fs.h (original)
+++ subversion/trunk/subversion/libsvn_fs_fs/fs.h Sun Mar 16 23:09:45 2014
@@ -242,6 +242,10 @@ typedef struct fs_fs_shared_data_t
      repository write lock. */
   svn_mutex__t *fs_write_lock;
 
+  /* A lock for intra-process synchronization when grabbing the
+     repository pack operation lock. */
+  svn_mutex__t *fs_pack_lock;
+
   /* A lock for intra-process synchronization when locking the
      txn-current file. */
   svn_mutex__t *txn_current_lock;

Modified: subversion/trunk/subversion/libsvn_fs_fs/fs_fs.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_fs/fs_fs.c?rev=1578176&r1=1578175&r2=1578176&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_fs/fs_fs.c (original)
+++ subversion/trunk/subversion/libsvn_fs_fs/fs_fs.c Sun Mar 16 23:09:45 2014
@@ -111,12 +111,18 @@ path_lock(svn_fs_t *fs, apr_pool_t *pool
   return svn_dirent_join(fs->path, PATH_LOCK_FILE, pool);
 }
 
+static APR_INLINE const char *
+path_pack_lock(svn_fs_t *fs, apr_pool_t *pool)
+{
+  return svn_dirent_join(fs->path, PATH_PACK_LOCK_FILE, pool);
+}
+
 
 
 /* Get a lock on empty file LOCK_FILENAME, creating it in POOL. */
-svn_error_t *
-svn_fs_fs__get_lock_on_filesystem(const char *lock_filename,
-                                  apr_pool_t *pool)
+static svn_error_t *
+get_lock_on_filesystem(const char *lock_filename,
+                       apr_pool_t *pool)
 {
   svn_error_t *err = svn_io_file_lock2(lock_filename, TRUE, FALSE, pool);
 
@@ -160,8 +166,7 @@ with_some_lock_file(svn_fs_t *fs,
                     apr_pool_t *pool)
 {
   apr_pool_t *subpool = svn_pool_create(pool);
-  svn_error_t *err = svn_fs_fs__get_lock_on_filesystem(lock_filename,
-                                                       subpool);
+  svn_error_t *err = get_lock_on_filesystem(lock_filename, subpool);
 
   if (!err)
     {
@@ -210,6 +215,25 @@ svn_fs_fs__with_write_lock(svn_fs_t *fs,
   return SVN_NO_ERROR;
 }
 
+svn_error_t *
+svn_fs_fs__with_pack_lock(svn_fs_t *fs,
+                          svn_error_t *(*body)(void *baton,
+                                               apr_pool_t *pool),
+                          void *baton,
+                          apr_pool_t *pool)
+{
+  fs_fs_data_t *ffd = fs->fsap_data;
+  fs_fs_shared_data_t *ffsd = ffd->shared;
+
+  SVN_MUTEX__WITH_LOCK(ffsd->fs_pack_lock,
+                       with_some_lock_file(fs, body, baton,
+                                           path_pack_lock(fs, pool),
+                                           FALSE,
+                                           pool));
+
+  return SVN_NO_ERROR;
+}
+
 /* Run BODY (with BATON and POOL) while the txn-current file
    of FS is locked. */
 svn_error_t *

Modified: subversion/trunk/subversion/libsvn_fs_fs/fs_fs.h
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_fs/fs_fs.h?rev=1578176&r1=1578175&r2=1578176&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_fs/fs_fs.h (original)
+++ subversion/trunk/subversion/libsvn_fs_fs/fs_fs.h Sun Mar 16 23:09:45 2014
@@ -136,12 +136,6 @@ svn_fs_fs__write_format(svn_fs_t *fs,
                         svn_boolean_t overwrite,
                         apr_pool_t *pool);
 
-/* Get a lock on empty file LOCK_FILENAME, creating it in POOL;
-   releasing the lock upon POOL cleanup. */
-svn_error_t *
-svn_fs_fs__get_lock_on_filesystem(const char *lock_filename,
-                                  apr_pool_t *pool);
-
 /* Obtain a write lock on the filesystem FS in a subpool of POOL, call
    BODY with BATON and that subpool, destroy the subpool (releasing the write
    lock) and return what BODY returned. */
@@ -152,6 +146,16 @@ svn_fs_fs__with_write_lock(svn_fs_t *fs,
                            void *baton,
                            apr_pool_t *pool);
 
+/* Obtain a pack operation lock on the filesystem FS in a subpool of POOL,
+   call BODY with BATON and that subpool, destroy the subpool (releasing the
+   write lock) and return what BODY returned. */
+svn_error_t *
+svn_fs_fs__with_pack_lock(svn_fs_t *fs,
+                          svn_error_t *(*body)(void *baton,
+                                               apr_pool_t *pool),
+                          void *baton,
+                          apr_pool_t *pool);
+
 /* Run BODY (with BATON and POOL) while the txn-current file
    of FS is locked. */
 svn_error_t *

Modified: subversion/trunk/subversion/libsvn_fs_fs/pack.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_fs/pack.c?rev=1578176&r1=1578175&r2=1578176&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_fs/pack.c (original)
+++ subversion/trunk/subversion/libsvn_fs_fs/pack.c Sun Mar 16 23:09:45 2014
@@ -2023,14 +2023,7 @@ svn_fs_fs__pack(svn_fs_t *fs,
          separate subpool here to release the lock immediately after the
          operation finished.
        */
-      apr_pool_t *subpool = svn_pool_create(pool);
-      const char *lock_path = svn_dirent_join(fs->path, PATH_PACK_LOCK_FILE,
-                                              subpool);
-      err = svn_fs_fs__get_lock_on_filesystem(lock_path, subpool);
-      if (!err)
-        err = pack_body(&pb, subpool);
-
-      svn_pool_destroy(subpool);
+      err = svn_fs_fs__with_pack_lock(fs, pack_body, &pb, pool);
     }
   else
     {


Reply via email to