subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From stef...@apache.org
Subject svn commit: r1611379 - /subversion/trunk/subversion/libsvn_subr/named_atomic.c
Date Thu, 17 Jul 2014 14:50:50 GMT
Author: stefan2
Date: Thu Jul 17 14:50:49 2014
New Revision: 1611379

URL: http://svn.apache.org/r1611379
Log:
Fix Windows redo loop oddity for named atomics.  As it turns out, the redo
loops for file creation and locking don't play very well with files that
get / got deleted.  This is the root cause for the bad ra_serf performance
when revprop caching has been enabled.

With this patch, we simply use the same lock file scheme as for e.g. lock
files in FSFS, i.e. we auto-create an empty lock file and keep it.

* subversion/libsvn_subr/named_atomic.c
  (mutex_t): Don't keep the lock file open while not holding the lock,
             i.e. the mutex is simply the file name and the pool that
             will contain the actual file lock.
  (lock): Auto-create and lock the file as we do in e.g. FSFS.
  (unlock): Simple pool cleanup now released the lock file.
  (delete_lock_file): Drop.
  (svn_atomic_namespace__create): Update mutex initialization code.

Modified:
    subversion/trunk/subversion/libsvn_subr/named_atomic.c

Modified: subversion/trunk/subversion/libsvn_subr/named_atomic.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_subr/named_atomic.c?rev=1611379&r1=1611378&r2=1611379&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_subr/named_atomic.c (original)
+++ subversion/trunk/subversion/libsvn_subr/named_atomic.c Thu Jul 17 14:50:49 2014
@@ -197,8 +197,8 @@ struct shared_data_t
  */
 struct mutex_t
 {
-  /* Inter-process sync. is handled by through lock file. */
-  apr_file_t *lock_file;
+  /* Inter-process sync. is handled by through a lock file. */
+  const char *lock_name;
 
   /* Pool to be used with lock / unlock functions */
   apr_pool_t *pool;
@@ -276,10 +276,23 @@ lock(struct mutex_t *mutex)
 {
   svn_error_t *err;
 
-  /* Get lock on the filehandle. */
+  /* Intra-process lock */
   SVN_ERR(svn_mutex__lock(thread_mutex));
-  err = svn_io_lock_open_file(mutex->lock_file, TRUE, FALSE, mutex->pool);
 
+  /* Inter-process lock. */
+  err = svn_io_file_lock2(mutex->lock_name, TRUE, FALSE, mutex->pool);
+  if (err && APR_STATUS_IS_ENOENT(err->apr_err))
+    {
+      /* No lock file?  No big deal; these are just empty files anyway.
+         Create it and try again. */
+      svn_error_clear(err);
+      err = NULL;
+
+      SVN_ERR(svn_io_file_create_empty(mutex->lock_name, mutex->pool));
+      SVN_ERR(svn_io_file_lock2(mutex->lock_name, TRUE, FALSE, mutex->pool));
+    }
+
+  /* Don't leave us in a semi-locked state ... */
   return err
     ? svn_mutex__unlock(thread_mutex, err)
     : err;
@@ -292,37 +305,10 @@ lock(struct mutex_t *mutex)
 static svn_error_t *
 unlock(struct mutex_t *mutex, svn_error_t * outer_err)
 {
-  svn_error_t *unlock_err
-      = svn_io_unlock_open_file(mutex->lock_file, mutex->pool);
-  return svn_mutex__unlock(thread_mutex,
-                           svn_error_compose_create(outer_err,
-                                                    unlock_err));
+  svn_pool_clear(mutex->pool);
+  return svn_mutex__unlock(thread_mutex, outer_err);
 }
 
-#if APR_HAS_MMAP
-/* The last user to close a particular namespace should also remove the
- * lock file.  Failure to do so, however, does not affect further uses
- * of the same namespace.
- */
-static apr_status_t
-delete_lock_file(void *arg)
-{
-  struct mutex_t *mutex = arg;
-  const char *lock_name = NULL;
-
-  /* locks have already been cleaned up. Simply close the file */
-  apr_status_t status = apr_file_close(mutex->lock_file);
-
-  /* Remove the file from disk. This will fail if there ares still other
-   * users of this lock file, i.e. namespace. */
-  apr_file_name_get(&lock_name, mutex->lock_file);
-  if (lock_name)
-    apr_file_remove(lock_name, mutex->pool);
-
-  return status;
-}
-#endif /* APR_HAS_MMAP */
-
 /* Validate the ATOMIC parameter, i.e it's address.  Correct code will
  * never need this but if someone should accidentally to use a NULL or
  * incomplete structure, let's catch that here instead of segfaulting.
@@ -411,29 +397,18 @@ svn_atomic_namespace__create(svn_atomic_
    */
   svn_atomic_namespace__t *new_ns = apr_pcalloc(result_pool, sizeof(**ns));
 
-  /* construct the names of the system objects that we need
+  /* construct the name of the system objects that we need
    */
   shm_name = apr_pstrcat(subpool, name, SHM_NAME_SUFFIX, SVN_VA_NULL);
-  lock_name = apr_pstrcat(subpool, name, MUTEX_NAME_SUFFIX, SVN_VA_NULL);
+  lock_name = apr_pstrcat(result_pool, name, MUTEX_NAME_SUFFIX, SVN_VA_NULL);
 
   /* initialize the lock objects
    */
   SVN_ERR(svn_atomic__init_once(&mutex_initialized, init_thread_mutex, NULL,
                                 result_pool));
 
-  new_ns->mutex.pool = result_pool;
-  SVN_ERR(svn_io_file_open(&new_ns->mutex.lock_file, lock_name,
-                           APR_READ | APR_WRITE | APR_CREATE,
-                           APR_OS_DEFAULT,
-                           result_pool));
-
-  /* Make sure the last user of our lock file will actually remove it.
-   * Please note that only the last file handle being closed will actually
-   * remove the underlying file (see docstring for apr_file_remove).
-   */
-  apr_pool_cleanup_register(result_pool, &new_ns->mutex,
-                            delete_lock_file,
-                            apr_pool_cleanup_null);
+  new_ns->mutex.pool = svn_pool_create(result_pool);
+  new_ns->mutex.lock_name = lock_name;
 
   /* Prevent concurrent initialization.
    */



Mime
View raw message