Skip to content

Commit 76a3c1c

Browse files
committed
Fix race between two concurrent critnib_remove() calls
Fix race between two concurrent critnib_remove() calls. Signed-off-by: Lukasz Dorau <[email protected]>
1 parent 1ae1fe6 commit 76a3c1c

File tree

1 file changed

+12
-5
lines changed

1 file changed

+12
-5
lines changed

src/critnib/critnib.c

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -590,11 +590,18 @@ void *critnib_remove(struct critnib *c, word key, void **ref) {
590590
c->pending_del_nodes[del] = n;
591591

592592
del_leaf:
593-
value = k->value;
594-
if (c->cb_free_leaf) {
595-
utils_atomic_store_release_ptr(&k->to_be_freed, value);
596-
utils_atomic_store_release_ptr(&k->value, NULL);
597-
*ref = k;
593+
utils_atomic_load_acquire_ptr(&k->value, &value);
594+
if (c->cb_free_leaf && value) {
595+
void *expected = value;
596+
void *desired = NULL;
597+
if (utils_compare_exchange_u64((uint64_t *)&k->value,
598+
(uint64_t *)&expected,
599+
(uint64_t *)&desired)) {
600+
utils_atomic_store_release_ptr(&k->to_be_freed, value);
601+
*ref = k;
602+
} else {
603+
value = NULL;
604+
}
598605
}
599606
c->pending_del_leaves[del] = k;
600607

0 commit comments

Comments
 (0)