From 05bdf0d74c094ff16ee280ceea09587004e43a7c Mon Sep 17 00:00:00 2001 From: Lukasz Dorau Date: Tue, 24 Jun 2025 11:52:59 +0200 Subject: [PATCH] Fix race between two concurrent critnib_remove() calls Fix race between two concurrent critnib_remove() calls. Signed-off-by: Lukasz Dorau --- src/critnib/critnib.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/critnib/critnib.c b/src/critnib/critnib.c index e8f5961c9..28ebced63 100644 --- a/src/critnib/critnib.c +++ b/src/critnib/critnib.c @@ -590,12 +590,21 @@ void *critnib_remove(struct critnib *c, word key, void **ref) { c->pending_del_nodes[del] = n; del_leaf: - value = k->value; - if (c->cb_free_leaf) { + utils_atomic_load_acquire_ptr(&k->value, &value); + if (c->cb_free_leaf && value) { + void *expected = value; + void *desired = NULL; + if (!utils_compare_exchange_u64((uint64_t *)&k->value, + (uint64_t *)&expected, + (uint64_t *)&desired)) { + value = NULL; + goto not_found; + } + utils_atomic_store_release_ptr(&k->to_be_freed, value); - utils_atomic_store_release_ptr(&k->value, NULL); *ref = k; } + c->pending_del_leaves[del] = k; not_found: