Author: stefan2
Date: Tue May 16 14:58:33 2017
New Revision: 1795322

URL: http://svn.apache.org/viewvc?rev=1795322&view=rev
Log:
Add debug code to the membuffer cache that detects disabled mutexes
while there are concurrent write accesses.

I ran into that situation when toying a round with multi-threaded
svnadmin operation.  It took me a while to figure out that svnadmin
created with cache in single-threaded mode, which caused random
crashes.

* subversion/libsvn_subr/cache-membuffer.c
  (svn_membuffer_t): Add a write lock counter.
  (svn_cache__membuffer_cache_create): Initilize the counter.
  (membuffer_cache_set_internal): Use assertions to update and check
                                  the new counter.

Modified:
    subversion/trunk/subversion/libsvn_subr/cache-membuffer.c

Modified: subversion/trunk/subversion/libsvn_subr/cache-membuffer.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_subr/cache-membuffer.c?rev=1795322&r1=1795321&r2=1795322&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_subr/cache-membuffer.c (original)
+++ subversion/trunk/subversion/libsvn_subr/cache-membuffer.c Tue May 16 
14:58:33 2017
@@ -812,6 +812,11 @@ struct svn_membuffer_t
    */
   svn_boolean_t allow_blocking_writes;
 #endif
+
+  /* A write lock counter, must be either 0 or 1.
+   * This one is only used in debug assertions to verify that you used
+   * the correct multi-threading settings. */
+  svn_atomic_t write_lock_count;
 };
 
 /* Align integer VALUE to the next ITEM_ALIGNMENT boundary.
@@ -2039,6 +2044,8 @@ svn_cache__membuffer_cache_create(svn_me
        */
       c[seg].allow_blocking_writes = allow_blocking_writes;
 #endif
+      /* No writers at the moment. */
+      c[seg].write_lock_count = 0;
     }
 
   /* done here
@@ -2198,6 +2205,10 @@ membuffer_cache_set_internal(svn_membuff
   /* first, look for a previous entry for the given key */
   entry_t *entry = find_entry(cache, group_index, to_find, FALSE);
 
+  /* If this one fails, you are using multiple threads but created the
+   * membuffer in single-threaded mode. */
+  assert(0 == svn_atomic_inc(&cache->write_lock_count));
+
   /* Quick check make sure arithmetics will work further down the road. */
   size = item_size + to_find->entry_key.key_len;
   if (size < item_size)
@@ -2237,6 +2248,10 @@ membuffer_cache_set_internal(svn_membuff
                item_size);
 
       cache->total_writes++;
+
+      /* Putting the decrement into an assert() to make it disappear
+       * in production code. */
+      assert(0 == svn_atomic_dec(&cache->write_lock_count));
       return SVN_NO_ERROR;
     }
 
@@ -2289,6 +2304,9 @@ membuffer_cache_set_internal(svn_membuff
         drop_entry(cache, entry);
     }
 
+  /* Putting the decrement into an assert() to make it disappear
+   * in production code. */
+  assert(0 == svn_atomic_dec(&cache->write_lock_count));
   return SVN_NO_ERROR;
 }
 


Reply via email to