mirror of
https://github.com/python/cpython.git
synced 2026-01-26 12:55:08 +00:00
gh-141805: Fix crash after concurrent addition objects with the same hash to set (GH-143815)
This happens when the set contained several elements with the same hash, and then some of them were removed.
This commit is contained in:
parent
f4de184980
commit
b8e925b4f8
@ -1853,6 +1853,7 @@ class TestWeirdBugs(unittest.TestCase):
|
||||
list(si)
|
||||
|
||||
def test_merge_and_mutate(self):
|
||||
# gh-141805
|
||||
class X:
|
||||
def __hash__(self):
|
||||
return hash(0)
|
||||
@ -1865,6 +1866,33 @@ class TestWeirdBugs(unittest.TestCase):
|
||||
s = {0}
|
||||
s.update(other)
|
||||
|
||||
def test_hash_collision_concurrent_add(self):
|
||||
class X:
|
||||
def __hash__(self):
|
||||
return 0
|
||||
class Y:
|
||||
flag = False
|
||||
def __hash__(self):
|
||||
return 0
|
||||
def __eq__(self, other):
|
||||
if not self.flag:
|
||||
self.flag = True
|
||||
s.add(X())
|
||||
return self is other
|
||||
|
||||
a = X()
|
||||
s = set()
|
||||
s.add(a)
|
||||
s.add(X())
|
||||
s.remove(a)
|
||||
# Now the set contains a dummy entry followed by an entry
|
||||
# for an object with hash 0.
|
||||
s.add(Y())
|
||||
# The following operations should not crash.
|
||||
repr(s)
|
||||
list(s)
|
||||
set() | s
|
||||
|
||||
|
||||
class TestOperationsMutating:
|
||||
"""Regression test for bpo-46615"""
|
||||
|
||||
@ -0,0 +1,3 @@
|
||||
Fix crash in :class:`set` when objects with the same hash are concurrently
|
||||
added to the set after removing an element with the same hash while the set
|
||||
still contains elements with the same hash.
|
||||
@ -308,6 +308,9 @@ set_add_entry_takeref(PySetObject *so, PyObject *key, Py_hash_t hash)
|
||||
found_unused_or_dummy:
|
||||
if (freeslot == NULL)
|
||||
goto found_unused;
|
||||
if (freeslot->hash != -1) {
|
||||
goto restart;
|
||||
}
|
||||
FT_ATOMIC_STORE_SSIZE_RELAXED(so->used, so->used + 1);
|
||||
FT_ATOMIC_STORE_SSIZE_RELAXED(freeslot->hash, hash);
|
||||
FT_ATOMIC_STORE_PTR_RELEASE(freeslot->key, key);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user