Skip to content

Commit ee90e8e

Browse files
luke-gruberluke-gru
authored andcommitted
Concurrent set fix when encountering garbage obj in find_or_insert
When CASing the garbage key to EMPTY, if we succeed we should decrease set->size because we're trying to re-insert into the same slot right after. The insertion increases set->size if it succeeds. This issue can lead to set->size being overcounted, which can lead to more table resizes.
1 parent ab32495 commit ee90e8e

1 file changed

Lines changed: 6 additions & 1 deletion

File tree

concurrent_set.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,12 @@ rb_concurrent_set_find_or_insert(VALUE *set_obj_ptr, VALUE key, void *data)
399399
if (continuation) {
400400
goto probe_next;
401401
}
402-
rbimpl_atomic_value_cas(&entry->key, curr_key, CONCURRENT_SET_EMPTY, RBIMPL_ATOMIC_RELEASE, RBIMPL_ATOMIC_RELAXED);
402+
{
403+
VALUE prev = rbimpl_atomic_value_cas(&entry->key, curr_key, CONCURRENT_SET_EMPTY, RBIMPL_ATOMIC_RELEASE, RBIMPL_ATOMIC_RELAXED);
404+
if (prev == curr_key) {
405+
rbimpl_atomic_sub(&set->size, 1, RBIMPL_ATOMIC_RELAXED);
406+
}
407+
}
403408
continue;
404409
}
405410

0 commit comments

Comments
 (0)