nscd: bump GC cycle during cache pruning (bug 26130)

Message ID mvmfta17yyi.fsf@suse.de
State Committed
Commit 5e74e6f85842892bc25da8e8c70d8dadd485941a
Headers
Series nscd: bump GC cycle during cache pruning (bug 26130) |

Commit Message

Andreas Schwab July 9, 2020, 10:41 a.m. UTC
  While nscd prunes a cache it becomes inconsistent temporarily, which is
visible to clients if that cache is shared.  Bump the GC cycle counter so
that the clients notice the modification window.

Use atomic_fetch_add to modify the GC cycle counter, including in the gc
function.
---
 nscd/cache.c | 9 +++++++++
 nscd/mem.c   | 4 ++--
 2 files changed, 11 insertions(+), 2 deletions(-)
  

Patch

diff --git a/nscd/cache.c b/nscd/cache.c
index 94163d9ce3..c0b9b4da3d 100644
--- a/nscd/cache.c
+++ b/nscd/cache.c
@@ -453,6 +453,11 @@  prune_cache (struct database_dyn *table, time_t now, int fd)
 	  pthread_rwlock_wrlock (&table->lock);
 	}
 
+      /* Now we start modifying the data.  Make sure all readers of the
+	 data are aware of this and temporarily don't use the data.  */
+      atomic_fetch_add_relaxed (&table->head->gc_cycle, 1);
+      assert ((table->head->gc_cycle & 1) == 1);
+
       while (first <= last)
 	{
 	  if (mark[first])
@@ -493,6 +498,10 @@  prune_cache (struct database_dyn *table, time_t now, int fd)
 	  ++first;
 	}
 
+      /* Now we are done modifying the data.  */
+      atomic_fetch_add_relaxed (&table->head->gc_cycle, 1);
+      assert ((table->head->gc_cycle & 1) == 0);
+
       /* It's all done.  */
       pthread_rwlock_unlock (&table->lock);
 
diff --git a/nscd/mem.c b/nscd/mem.c
index 3d10bb9b46..de5bd12db5 100644
--- a/nscd/mem.c
+++ b/nscd/mem.c
@@ -264,7 +264,7 @@  gc (struct database_dyn *db)
 
   /* Now we start modifying the data.  Make sure all readers of the
      data are aware of this and temporarily don't use the data.  */
-  ++db->head->gc_cycle;
+  atomic_fetch_add_relaxed (&db->head->gc_cycle, 1);
   assert ((db->head->gc_cycle & 1) == 1);
 
 
@@ -490,7 +490,7 @@  gc (struct database_dyn *db)
 
 
   /* Now we are done modifying the data.  */
-  ++db->head->gc_cycle;
+  atomic_fetch_add_relaxed (&db->head->gc_cycle, 1);
   assert ((db->head->gc_cycle & 1) == 0);
 
   /* We are done.  */