]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/basic/hashmap.c
Merge pull request #2153 from evverx/fix-verify-for-templates
[thirdparty/systemd.git] / src / basic / hashmap.c
index e5f05f36f8fb93daf02b744d0cf5791f7ee1a9cc..286ddfef5b38024d201460469c90601dfa05d1ce 100644 (file)
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
-#include <stdlib.h>
 #include <errno.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
 
-#include "util.h"
+#include "alloc-util.h"
 #include "hashmap.h"
-#include "set.h"
 #include "macro.h"
-#include "siphash24.h"
-#include "strv.h"
 #include "mempool.h"
+#include "process-util.h"
 #include "random-util.h"
+#include "set.h"
+#include "siphash24.h"
+#include "strv.h"
+#include "util.h"
 
 #ifdef ENABLE_DEBUG_HASHMAP
+#include <pthread.h>
 #include "list.h"
 #endif
 
@@ -157,6 +162,7 @@ struct hashmap_debug_info {
 
 /* Tracks all existing hashmaps. Get at it from gdb. See sd_dump_hashmaps.py */
 static LIST_HEAD(struct hashmap_debug_info, hashmap_debug_list);
+static pthread_mutex_t hashmap_debug_list_mutex = PTHREAD_MUTEX_INITIALIZER;
 
 #define HASHMAP_DEBUG_FIELDS struct hashmap_debug_info debug;
 
@@ -274,10 +280,8 @@ static const struct hashmap_type_info hashmap_type_info[_HASHMAP_TYPE_MAX] = {
         },
 };
 
-unsigned long string_hash_func(const void *p, const uint8_t hash_key[HASH_KEY_SIZE]) {
-        uint64_t u;
-        siphash24((uint8_t*) &u, p, strlen(p), hash_key);
-        return (unsigned long) u;
+void string_hash_func(const void *p, struct siphash *state) {
+        siphash24_compress(p, strlen(p) + 1, state);
 }
 
 int string_compare_func(const void *a, const void *b) {
@@ -289,10 +293,8 @@ const struct hash_ops string_hash_ops = {
         .compare = string_compare_func
 };
 
-unsigned long trivial_hash_func(const void *p, const uint8_t hash_key[HASH_KEY_SIZE]) {
-        uint64_t u;
-        siphash24((uint8_t*) &u, &p, sizeof(p), hash_key);
-        return (unsigned long) u;
+void trivial_hash_func(const void *p, struct siphash *state) {
+        siphash24_compress(&p, sizeof(p), state);
 }
 
 int trivial_compare_func(const void *a, const void *b) {
@@ -304,10 +306,8 @@ const struct hash_ops trivial_hash_ops = {
         .compare = trivial_compare_func
 };
 
-unsigned long uint64_hash_func(const void *p, const uint8_t hash_key[HASH_KEY_SIZE]) {
-        uint64_t u;
-        siphash24((uint8_t*) &u, p, sizeof(uint64_t), hash_key);
-        return (unsigned long) u;
+void uint64_hash_func(const void *p, struct siphash *state) {
+        siphash24_compress(p, sizeof(uint64_t), state);
 }
 
 int uint64_compare_func(const void *_a, const void *_b) {
@@ -323,10 +323,8 @@ const struct hash_ops uint64_hash_ops = {
 };
 
 #if SIZEOF_DEV_T != 8
-unsigned long devt_hash_func(const void *p, const uint8_t hash_key[HASH_KEY_SIZE]) {
-        uint64_t u;
-        siphash24((uint8_t*) &u, p, sizeof(dev_t), hash_key);
-        return (unsigned long) u;
+void devt_hash_func(const void *p, struct siphash *state) {
+        siphash24_compress(p, sizeof(dev_t), state);
 }
 
 int devt_compare_func(const void *_a, const void *_b) {
@@ -377,7 +375,16 @@ static uint8_t *hash_key(HashmapBase *h) {
 }
 
 static unsigned base_bucket_hash(HashmapBase *h, const void *p) {
-        return (unsigned) (h->hash_ops->hash(p, hash_key(h)) % n_buckets(h));
+        struct siphash state;
+        uint64_t hash;
+
+        siphash24_init(&state, hash_key(h));
+
+        h->hash_ops->hash(p, &state);
+
+        hash = siphash24_finalize(&state);
+
+        return (unsigned) (hash % n_buckets(h));
 }
 #define bucket_hash(h, p) base_bucket_hash(HASHMAP_BASE(h), p)
 
@@ -806,10 +813,12 @@ static struct HashmapBase *hashmap_base_new(const struct hash_ops *hash_ops, enu
         }
 
 #ifdef ENABLE_DEBUG_HASHMAP
-        LIST_PREPEND(debug_list, hashmap_debug_list, &h->debug);
         h->debug.func = func;
         h->debug.file = file;
         h->debug.line = line;
+        assert_se(pthread_mutex_lock(&hashmap_debug_list_mutex) == 0);
+        LIST_PREPEND(debug_list, hashmap_debug_list, &h->debug);
+        assert_se(pthread_mutex_unlock(&hashmap_debug_list_mutex) == 0);
 #endif
 
         return h;
@@ -861,7 +870,9 @@ static void hashmap_free_no_clear(HashmapBase *h) {
         assert(!h->n_direct_entries);
 
 #ifdef ENABLE_DEBUG_HASHMAP
+        assert_se(pthread_mutex_lock(&hashmap_debug_list_mutex) == 0);
         LIST_REMOVE(debug_list, hashmap_debug_list, &h->debug);
+        assert_se(pthread_mutex_unlock(&hashmap_debug_list_mutex) == 0);
 #endif
 
         if (h->from_pool)