Skip to content

Commit bbc0359

Browse files
vstinnernascheme
andcommitted
pythongh-151593: Fix dead lock in PyDict insert_split_key()
Do not hold LOCK_KEYS() lock when calling PyType_Modified() to avoid a deadlock. Co-authored-by: Neil Schemenauer <nas-github@arctrix.com>
1 parent b6d89ed commit bbc0359

1 file changed

Lines changed: 9 additions & 1 deletion

File tree

‎Objects/dictobject.c‎

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1923,12 +1923,13 @@ insert_split_key(PyDictKeysObject *keys, PyObject *key, Py_hash_t hash)
19231923
}
19241924
#endif
19251925

1926+
bool inserted = false;
19261927
LOCK_KEYS(keys);
19271928
ix = unicodekeys_lookup_unicode(keys, key, hash);
19281929
if (ix == DKIX_EMPTY && keys->dk_usable > 0) {
19291930
// Insert into new slot
1931+
inserted = true;
19301932
FT_ATOMIC_STORE_UINT32_RELAXED(keys->dk_version, 0);
1931-
_PyDict_SplitKeysInvalidated(keys);
19321933
Py_ssize_t hashpos = find_empty_slot(keys, hash);
19331934
ix = keys->dk_nentries;
19341935
dictkeys_set_index(keys, hashpos, ix);
@@ -1938,6 +1939,13 @@ insert_split_key(PyDictKeysObject *keys, PyObject *key, Py_hash_t hash)
19381939
}
19391940
assert (ix < SHARED_KEYS_MAX_SIZE);
19401941
UNLOCK_KEYS(keys);
1942+
1943+
if (inserted) {
1944+
// gh-151593: Calling PyType_Modified() with LOCK_KEYS() creates a
1945+
// deadlock. So only call the function after UNLOCK_KEYS().
1946+
_PyDict_SplitKeysInvalidated(keys);
1947+
}
1948+
19411949
return ix;
19421950
}
19431951

0 commit comments

Comments
 (0)