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
{