]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Use atomics for the iterators number in isc_hashmap_t
authorAram Sargsyan <aram@isc.org>
Tue, 7 Nov 2023 10:21:36 +0000 (10:21 +0000)
committerAram Sargsyan <aram@isc.org>
Tue, 14 Nov 2023 08:56:41 +0000 (08:56 +0000)
Concurrent threads can access a hashmap for reading by creating and
then destroying an iterator, in which case the integer number of the
active iterators is increased or decreased from different threads,
introducing a data race. Use atomic operations to protect the variable.

lib/isc/hashmap.c

index 5927b52cc99799b7890d7f7f0e15ed9776b0305c..d0611b97d37fdf1f879cd9fd0725112ef37c8b5c 100644 (file)
@@ -31,6 +31,7 @@
 #include <string.h>
 
 #include <isc/ascii.h>
+#include <isc/atomic.h>
 #include <isc/entropy.h>
 #include <isc/hash.h>
 #include <isc/hashmap.h>
@@ -87,7 +88,7 @@ struct isc_hashmap {
        isc_mem_t *mctx;
        size_t count;
        hashmap_table_t tables[HASHMAP_NUM_TABLES];
-       uint_fast32_t iterators;
+       atomic_uint_fast32_t iterators;
 };
 
 struct isc_hashmap_iter {
@@ -352,7 +353,7 @@ hashmap_rehash_one(isc_hashmap_t *hashmap) {
        hashmap_node_t node;
 
        /* Don't rehash when iterating */
-       INSIST(hashmap->iterators == 0);
+       INSIST(atomic_load_acquire(&hashmap->iterators) == 0);
 
        /* Find first non-empty node */
        while (hashmap->hiter < oldsize && oldtable[hashmap->hiter].key == NULL)
@@ -506,7 +507,7 @@ hashmap_add(isc_hashmap_t *hashmap, const uint32_t hashval,
        hashmap_node_t *current = NULL;
        uint32_t pos;
 
-       INSIST(hashmap->iterators == 0);
+       INSIST(atomic_load_acquire(&hashmap->iterators) == 0);
 
        hash = isc_hash_bits32(hashval, hashmap->tables[idx].hashbits);
 
@@ -605,7 +606,7 @@ isc_hashmap_iter_create(isc_hashmap_t *hashmap, isc_hashmap_iter_t **iterp) {
                .hindex = hashmap->hindex,
        };
 
-       hashmap->iterators++;
+       (void)atomic_fetch_add_release(&hashmap->iterators, 1);
 
        *iterp = iter;
 }
@@ -622,8 +623,7 @@ isc_hashmap_iter_destroy(isc_hashmap_iter_t **iterp) {
        hashmap = iter->hashmap;
        isc_mem_put(hashmap->mctx, iter, sizeof(*iter));
 
-       INSIST(hashmap->iterators > 0);
-       hashmap->iterators--;
+       INSIST(atomic_fetch_sub_release(&hashmap->iterators, 1) > 0);
 }
 
 static isc_result_t