Skip to content

Commit 05bdf0d

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 e9fdb84 commit 05bdf0d

File tree

1 file changed

+12
-3
lines changed

1 file changed

+12
-3
lines changed

src/critnib/critnib.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -590,12 +590,21 @@ 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) {
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+
value = NULL;
601+
goto not_found;
602+
}
603+
595604
utils_atomic_store_release_ptr(&k->to_be_freed, value);
596-
utils_atomic_store_release_ptr(&k->value, NULL);
597605
*ref = k;
598606
}
607+
599608
c->pending_del_leaves[del] = k;
600609

601610
not_found:

0 commit comments

Comments
 (0)