@@ -1952,6 +1952,10 @@ insert_split_key(PyDictKeysObject *keys, PyObject *key, Py_hash_t hash)
19521952 return ix ;
19531953 }
19541954
1955+ // We need to acquire the type lock before the keys mutex. Another lock
1956+ // is never acquired below the keys mutex but a keys mutex can be acquired
1957+ // elsewhere while we hold the types lock. To avoid deadlocks we must always
1958+ // acquire the type lock first.
19551959 Py_BEGIN_CRITICAL_SECTION_MUTEX (& _PyInterpreterState_GET ()-> types .mutex );
19561960#endif
19571961
@@ -1960,7 +1964,12 @@ insert_split_key(PyDictKeysObject *keys, PyObject *key, Py_hash_t hash)
19601964 if (ix == DKIX_EMPTY && keys -> dk_usable > 0 ) {
19611965 // Insert into new slot
19621966 FT_ATOMIC_STORE_UINT32_RELAXED (keys -> dk_version , 0 );
1963- _PyDict_SplitKeysInvalidated (keys );
1967+ struct _instancekeysobject * shared_keys = _PyDictKeys_AsSharedKeys (keys );
1968+ PyTypeObject * type = FT_ATOMIC_LOAD_PTR_ACQUIRE (shared_keys -> dsk_owning_type );
1969+ if (type ) {
1970+ // we acquired the type lock above
1971+ _PyType_Modified_Unlocked (type );
1972+ }
19641973 Py_ssize_t hashpos = find_empty_slot (keys , hash );
19651974 ix = keys -> dk_nentries ;
19661975 dictkeys_set_index (keys , hashpos , ix );
@@ -7293,16 +7302,6 @@ _PyDict_RemoveKeysForClass(PyHeapTypeObject *cls)
72937302 _PyDictKeys_DecRef (cls -> ht_cached_keys );
72947303}
72957304
7296- void
7297- _PyDict_SplitKeysInvalidated (PyDictKeysObject * keys )
7298- {
7299- struct _instancekeysobject * shared_keys = _PyDictKeys_AsSharedKeys (keys );
7300- PyTypeObject * type = FT_ATOMIC_LOAD_PTR_ACQUIRE (shared_keys -> dsk_owning_type );
7301- if (type ) {
7302- _PyType_Modified_Unlocked (type );
7303- }
7304- }
7305-
73067305void
73077306_PyObject_InitInlineValues (PyObject * obj , PyTypeObject * tp )
73087307{
0 commit comments