Attached is a better patch that avoids the non-portable (and ugly) recursive mutex in favor of properly releasing the lock before reacquiring it.
>From 460c14e1db1d1cab5f405f21e4a28a39c5721a36 Mon Sep 17 00:00:00 2001 From: Eric Wong <normalper...@yhbt.net> Date: Sat, 20 Oct 2012 04:17:43 +0000 Subject: [PATCH] avoid mutex deadlock in stat_cache_get()
stat_cache_get() could lead to pthread_mutex_lock(&stat_cache_mutex) being called twice in the same thread without a matching pthread_mutex_unlock: stat_cache_get() - locks stat_cache_mutex file_cache_unref() file_cache_sync_unlocked() stat_cache_invalidate() -> locks stat_cache_mutex again By releasing stat_cache_mutex before calling file_cache_unref(), we can ensure stat_cache_invalidate() won't attempt to lock a mutex the current thread already holds. ref: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=691010 --- src/statcache.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/statcache.c b/src/statcache.c index d9e801f..83e6ca1 100644 --- a/src/statcache.c +++ b/src/statcache.c @@ -100,16 +100,15 @@ int stat_cache_get(const char *fn, struct stat *st) { time(NULL) <= ce->stat_info.dead) { *st = ce->stat_info.st; - - if ((f = file_cache_get(fn))) { - st->st_size = file_cache_get_size(f); - file_cache_unref(f); - } - r = 0; } pthread_mutex_unlock(&stat_cache_mutex); + + if ((r == 0) && (f = file_cache_get(fn))) { + st->st_size = file_cache_get_size(f); + file_cache_unref(f); + } return r; } -- 1.8.0.rc3.16.g8ead1bf