diff --git a/nscd/connections.c b/nscd/connections.c index e3a6738..597e1a7 100644 --- nscd/connections.c +++ nscd/connections.c @@ -109,6 +109,7 @@ struct database_dyn dbs[lastdb] = [pwddb] = { .lock = PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP, .prune_lock = PTHREAD_MUTEX_INITIALIZER, + .prune_run_lock = PTHREAD_MUTEX_INITIALIZER, .enabled = 0, .check_file = 1, .persistent = 0, @@ -129,6 +130,7 @@ struct database_dyn dbs[lastdb] = [grpdb] = { .lock = PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP, .prune_lock = PTHREAD_MUTEX_INITIALIZER, + .prune_run_lock = PTHREAD_MUTEX_INITIALIZER, .enabled = 0, .check_file = 1, .persistent = 0, @@ -149,6 +151,7 @@ struct database_dyn dbs[lastdb] = [hstdb] = { .lock = PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP, .prune_lock = PTHREAD_MUTEX_INITIALIZER, + .prune_run_lock = PTHREAD_MUTEX_INITIALIZER, .enabled = 0, .check_file = 1, .persistent = 0, @@ -169,6 +172,7 @@ struct database_dyn dbs[lastdb] = [servdb] = { .lock = PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP, .prune_lock = PTHREAD_MUTEX_INITIALIZER, + .prune_run_lock = PTHREAD_MUTEX_INITIALIZER, .enabled = 0, .check_file = 1, .persistent = 0, @@ -975,9 +979,9 @@ invalidate_cache (char *key, int fd) if (dbs[number].enabled) { - pthread_mutex_lock (&dbs[number].prune_lock); + pthread_mutex_lock (&dbs[number].prune_run_lock); prune_cache (&dbs[number], LONG_MAX, fd); - pthread_mutex_unlock (&dbs[number].prune_lock); + pthread_mutex_unlock (&dbs[number].prune_run_lock); } else { @@ -1492,6 +1496,7 @@ nscd_run_prune (void *p) dbs[my_number].wakeup_time = now + CACHE_PRUNE_INTERVAL + my_number; pthread_mutex_t *prune_lock = &dbs[my_number].prune_lock; + pthread_mutex_t *prune_run_lock = &dbs[my_number].prune_run_lock; pthread_cond_t *prune_cond = &dbs[my_number].prune_cond; pthread_mutex_lock (prune_lock); @@ -1523,7 +1528,10 @@ nscd_run_prune (void *p) time_t prune_now = dbs[my_number].clear_cache ? LONG_MAX : now; dbs[my_number].clear_cache = 0; + /* prune_cache() must be run with prune_lock off since + cache_add() needs to take the lock. */ pthread_mutex_unlock (prune_lock); + pthread_mutex_lock (prune_run_lock); next_wait = prune_cache (&dbs[my_number], prune_now, -1); @@ -1538,6 +1546,7 @@ nscd_run_prune (void *p) dbs[my_number].head->timestamp = now; } + pthread_mutex_unlock (prune_run_lock); pthread_mutex_lock (prune_lock); /* Make it known when we will wake up again. */ diff --git a/nscd/nscd.h b/nscd/nscd.h index 5c77dd3..a828f3e 100644 --- nscd/nscd.h +++ nscd/nscd.h @@ -68,7 +68,7 @@ struct database_dyn { pthread_rwlock_t lock; pthread_cond_t prune_cond; - pthread_mutex_t prune_lock; + pthread_mutex_t prune_lock, prune_run_lock; time_t wakeup_time; int enabled;