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;
}