You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2011/12/16 11:35:07 UTC
svn commit: r1215083 - in /subversion/trunk/subversion:
include/private/svn_cache.h libsvn_fs_fs/caching.c
libsvn_subr/cache-membuffer.c tests/libsvn_subr/cache-test.c
Author: stefan2
Date: Fri Dec 16 10:35:06 2011
New Revision: 1215083
URL: http://svn.apache.org/viewvc?rev=1215083&view=rev
Log:
Offer optional thread-safety for membuffer cache frontends
(actual data container / backend is already thread-safe).
The membuffer cache is now on par with inprocess cache
features.
* subversion/include/private/svn_cache.h
(svn_cache__create_membuffer_cache): add thread_safe parameter
* subversion/libsvn_subr/cache-membuffer.c
(svn_membuffer_cache_t): add optional mutex
(svn_membuffer_cache_get, svn_membuffer_cache_set,
svn_membuffer_cache_get_partial, svn_membuffer_cache_set_partial,
svn_membuffer_cache_is_cachable, svn_membuffer_cache_get_info,
membuffer_cache_vtable): mark as non-sync'ing in docstring
(svn_membuffer_cache_get_synced, svn_membuffer_cache_set_synced,
svn_membuffer_cache_get_partial_synced,
svn_membuffer_cache_set_partial_synced): new sync'ing wrappers
around the non-sync'ing implementations
(membuffer_cache_synced_vtable): new vtable for sync'ing caches
(svn_cache__create_membuffer_cache): depending on thread_safe
parameter, initialize mutex and select proper vtable
* subversion/libsvn_fs_fs/caching.c
(create_cache): adapt caller to provided additional parameter
* subversion/tests/libsvn_subr/cache-test.c
(test_membuffer_cache_basic): dito
Modified:
subversion/trunk/subversion/include/private/svn_cache.h
subversion/trunk/subversion/libsvn_fs_fs/caching.c
subversion/trunk/subversion/libsvn_subr/cache-membuffer.c
subversion/trunk/subversion/tests/libsvn_subr/cache-test.c
Modified: subversion/trunk/subversion/include/private/svn_cache.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/private/svn_cache.h?rev=1215083&r1=1215082&r2=1215083&view=diff
==============================================================================
--- subversion/trunk/subversion/include/private/svn_cache.h (original)
+++ subversion/trunk/subversion/include/private/svn_cache.h Fri Dec 16 10:35:06 2011
@@ -295,8 +295,9 @@ svn_cache__membuffer_cache_create(svn_me
* svn_string_t; if @a serialize_func is NULL, then the data is
* assumed to be an svn_stringbuf_t.
*
- * These caches themselves are thread safe, the shared @a memcache may
- * be not, depending on its creation parameters.
+ * If @a thread_safe is true, and APR is compiled with threads, all
+ * accesses to the cache will be protected with a mutex, if the shared
+ * @a memcache has also been created with thread_safe flag set.
*
* These caches do not support svn_cache__iter.
*/
@@ -307,6 +308,7 @@ svn_cache__create_membuffer_cache(svn_ca
svn_cache__deserialize_func_t deserialize,
apr_ssize_t klen,
const char *prefix,
+ svn_boolean_t thread_safe,
apr_pool_t *result_pool);
/**
Modified: subversion/trunk/subversion/libsvn_fs_fs/caching.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_fs/caching.c?rev=1215083&r1=1215082&r2=1215083&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_fs/caching.c (original)
+++ subversion/trunk/subversion/libsvn_fs_fs/caching.c Fri Dec 16 10:35:06 2011
@@ -219,7 +219,7 @@ create_cache(svn_cache__t **cache_p,
{
SVN_ERR(svn_cache__create_membuffer_cache(
cache_p, membuffer, serializer, deserializer,
- klen, prefix, pool));
+ klen, prefix, FALSE, pool));
}
else if (pages)
{
Modified: subversion/trunk/subversion/libsvn_subr/cache-membuffer.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_subr/cache-membuffer.c?rev=1215083&r1=1215082&r2=1215083&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_subr/cache-membuffer.c (original)
+++ subversion/trunk/subversion/libsvn_subr/cache-membuffer.c Fri Dec 16 10:35:06 2011
@@ -1567,6 +1567,9 @@ typedef struct svn_membuffer_cache_t
*/
int alloc_counter;
+ /* if enabled, this will serialize the access to this instance.
+ */
+ svn_mutex__t *mutex;
#ifdef SVN_DEBUG_CACHE_MEMBUFFER
/* Invariant tag info for all items stored by this cache instance.
@@ -1604,7 +1607,7 @@ combine_key(const void *prefix,
memcpy((char *)*full_key + prefix_len, key, key_len);
}
-/* Implement svn_cache__vtable_t.get
+/* Implement svn_cache__vtable_t.get (not thread-safe)
*/
static svn_error_t *
svn_membuffer_cache_get(void **value_p,
@@ -1655,7 +1658,7 @@ svn_membuffer_cache_get(void **value_p,
return SVN_NO_ERROR;
}
-/* Implement svn_cache__vtable_t.set
+/* Implement svn_cache__vtable_t.set (not thread-safe)
*/
static svn_error_t *
svn_membuffer_cache_set(void *cache_void,
@@ -1716,7 +1719,7 @@ svn_membuffer_cache_iter(svn_boolean_t *
_("Can't iterate a membuffer-based cache"));
}
-/* Implement svn_cache__vtable_t.get_partial
+/* Implement svn_cache__vtable_t.get_partial (not thread-safe)
*/
static svn_error_t *
svn_membuffer_cache_get_partial(void **value_p,
@@ -1761,7 +1764,7 @@ svn_membuffer_cache_get_partial(void **v
return SVN_NO_ERROR;
}
-/* Implement svn_cache__vtable_t.set_partial
+/* Implement svn_cache__vtable_t.set_partial (not thread-safe)
*/
static svn_error_t *
svn_membuffer_cache_set_partial(void *cache_void,
@@ -1797,6 +1800,7 @@ svn_membuffer_cache_set_partial(void *ca
}
/* Implement svn_cache__vtable_t.is_cachable
+ * (thread-safe even without mutex)
*/
static svn_boolean_t
svn_membuffer_cache_is_cachable(void *cache_void, apr_size_t size)
@@ -1828,6 +1832,7 @@ svn_membuffer_get_segment_info(svn_membu
}
/* Implement svn_cache__vtable_t.get_info
+ * (thread-safe even without mutex)
*/
static svn_error_t *
svn_membuffer_cache_get_info(void *cache_void,
@@ -1862,7 +1867,7 @@ svn_membuffer_cache_get_info(void *cache
}
-/* the v-table for membuffer-based caches
+/* the v-table for membuffer-based caches (single-threaded access)
*/
static svn_cache__vtable_t membuffer_cache_vtable = {
svn_membuffer_cache_get,
@@ -1874,6 +1879,100 @@ static svn_cache__vtable_t membuffer_cac
svn_membuffer_cache_get_info
};
+/* Implement svn_cache__vtable_t.get and serialize all cache access.
+ */
+static svn_error_t *
+svn_membuffer_cache_get_synced(void **value_p,
+ svn_boolean_t *found,
+ void *cache_void,
+ const void *key,
+ apr_pool_t *result_pool)
+{
+ svn_membuffer_cache_t *cache = cache_void;
+ SVN_MUTEX__WITH_LOCK(cache->mutex,
+ svn_membuffer_cache_get(value_p,
+ found,
+ cache_void,
+ key,
+ result_pool));
+
+ return SVN_NO_ERROR;
+}
+
+/* Implement svn_cache__vtable_t.set and serialize all cache access.
+ */
+static svn_error_t *
+svn_membuffer_cache_set_synced(void *cache_void,
+ const void *key,
+ void *value,
+ apr_pool_t *scratch_pool)
+{
+ svn_membuffer_cache_t *cache = cache_void;
+ SVN_MUTEX__WITH_LOCK(cache->mutex,
+ svn_membuffer_cache_set(cache_void,
+ key,
+ value,
+ scratch_pool));
+
+ return SVN_NO_ERROR;
+}
+
+/* Implement svn_cache__vtable_t.get_partial and serialize all cache access.
+ */
+static svn_error_t *
+svn_membuffer_cache_get_partial_synced(void **value_p,
+ svn_boolean_t *found,
+ void *cache_void,
+ const void *key,
+ svn_cache__partial_getter_func_t func,
+ void *baton,
+ apr_pool_t *result_pool)
+{
+ svn_membuffer_cache_t *cache = cache_void;
+ SVN_MUTEX__WITH_LOCK(cache->mutex,
+ svn_membuffer_cache_get_partial(value_p,
+ found,
+ cache_void,
+ key,
+ func,
+ baton,
+ result_pool));
+
+ return SVN_NO_ERROR;
+}
+
+/* Implement svn_cache__vtable_t.set_partial and serialize all cache access.
+ */
+static svn_error_t *
+svn_membuffer_cache_set_partial_synced(void *cache_void,
+ const void *key,
+ svn_cache__partial_setter_func_t func,
+ void *baton,
+ apr_pool_t *scratch_pool)
+{
+ svn_membuffer_cache_t *cache = cache_void;
+ SVN_MUTEX__WITH_LOCK(cache->mutex,
+ svn_membuffer_cache_set_partial(cache_void,
+ key,
+ func,
+ baton,
+ scratch_pool));
+
+ return SVN_NO_ERROR;
+}
+
+/* the v-table for membuffer-based caches with multi-threading support)
+ */
+static svn_cache__vtable_t membuffer_cache_synced_vtable = {
+ svn_membuffer_cache_get_synced,
+ svn_membuffer_cache_set_synced,
+ svn_membuffer_cache_iter, /* no sync required */
+ svn_membuffer_cache_is_cachable, /* no sync required */
+ svn_membuffer_cache_get_partial_synced,
+ svn_membuffer_cache_set_partial_synced,
+ svn_membuffer_cache_get_info /* no sync required */
+};
+
/* standard serialization function for svn_stringbuf_t items.
* Implements svn_cache__serialize_func_t.
*/
@@ -1918,6 +2017,7 @@ svn_cache__create_membuffer_cache(svn_ca
svn_cache__deserialize_func_t deserializer,
apr_ssize_t klen,
const char *prefix,
+ svn_boolean_t thread_safe,
apr_pool_t *pool)
{
svn_checksum_t *checksum;
@@ -1941,6 +2041,8 @@ svn_cache__create_membuffer_cache(svn_ca
cache->pool = svn_pool_create(pool);
cache->alloc_counter = 0;
+ SVN_ERR(svn_mutex__init(&cache->mutex, thread_safe, pool));
+
/* for performance reasons, we don't actually store the full prefix but a
* hash value of it
*/
@@ -1961,7 +2063,8 @@ svn_cache__create_membuffer_cache(svn_ca
/* initialize the generic cache wrapper
*/
- wrapper->vtable = &membuffer_cache_vtable;
+ wrapper->vtable = thread_safe ? &membuffer_cache_synced_vtable
+ : &membuffer_cache_vtable;
wrapper->cache_internal = cache;
wrapper->error_handler = 0;
wrapper->error_baton = 0;
Modified: subversion/trunk/subversion/tests/libsvn_subr/cache-test.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/libsvn_subr/cache-test.c?rev=1215083&r1=1215082&r2=1215083&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_subr/cache-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_subr/cache-test.c Fri Dec 16 10:35:06 2011
@@ -193,6 +193,7 @@ test_membuffer_cache_basic(apr_pool_t *p
deserialize_revnum,
APR_HASH_KEY_STRING,
"cache:",
+ FALSE,
pool));
return basic_cache_test(cache, FALSE, pool);