Actually, the following might suffice for now:

Index: subversion/libsvn_subr/cache-inprocess.c
===================================================================
--- subversion/libsvn_subr/cache-inprocess.c    (revision 1124903)
+++ subversion/libsvn_subr/cache-inprocess.c    (working copy)
@@ -148,19 +148,19 @@ insert_page(inprocess_cache_t *cache,
 
 /* If PAGE is in the circularly linked list (eg, its NEXT isn't NULL),
  * move it to the front of the list. */
-static svn_error_t *
+static void
 move_page_to_front(inprocess_cache_t *cache,
                    struct cache_page *page)
 {
-  SVN_ERR_ASSERT(page != cache->sentinel);
+  SVN_ERR_ASSERT_NO_RETURN(page != cache->sentinel);
 
   if (! page->next)
-    return SVN_NO_ERROR;
+    return;
 
   remove_page_from_list(page);
   insert_page(cache, page);
 
-  return SVN_NO_ERROR;
+  return;
 }
 
 /* Return a copy of KEY inside POOL, using CACHE->KLEN to figure out

Daniel Shahaf wrote on Thu, May 19, 2011 at 17:01:15 +0200:
> In inprocess-cache.c the following pattern is common:
> 
> svn_error_t *inprocess_callback()
> {
>   SVN_ERR(lock_cache(cache));
>   SVN_ERR(body());
>   SVN_ERR(unlock_cache(cache));
>   return something;
> }
> 
> So, if an error occurs, then all future cache calls deadlock; and it's
> easy to forget to balance lock/unlock calls even by accident.
> 
> Suggestions:
> 
> * Move to a with_cache_locked() callback paradigm, as already done in
>   FSFS and libsvn_wc.  This is harder to read but will encourage
>   minimizing critical sections and will ensure that the cache is
>   properly unlocked on non-fatal error conditions (i.e., those that
>   don't correspond to a corrupted cache).
> 
> * Alternatively, add SVN_ERR_ASSERT(cache->is_locked) to relevant
>   helper functions.  This will ensure that locks are either cleared or
>   (if stale) noisily complained about, but not deadlock.
> 
> * If body() discovers a fatal error condition... well, we could just
>   SVN_ERR_ASSERT() out.  Or we could set cache->malfunctioning := TRUE
>   and then check that at all entry points.
> 
> * [ this is somewhat orthogonal ]
> 
>   The cache passes through (unmodified) all errors from the
>   serialize/deserialize functions.  Aren't them some conditions that
>   we'd like those callbacks to be able to signal (to the cache or to
>   the cache's user)?  For example:
>   SVN_ERR_CACHE_CORRUPT
>   SVN_ERR_CACHE_DESERIALIZE_SAID_NOT_FOUND
>   SVN_ERR_CACHE_DESERIALIZE_FAILED
> 
> Thoughts?
> 
> Barring objections I'll look into implementing something that eliminates
> the potential deadlock.

Reply via email to