Fix race in constructing dict for instance · python/cpython@12d0685 · GitHub
Skip to content

Commit 12d0685

Browse files
committed
Fix race in constructing dict for instance
1 parent a37b093 commit 12d0685

3 files changed

Lines changed: 23 additions & 24 deletions

File tree

Include/internal/pycore_dict.h

Lines changed: 1 addition & 1 deletion

Objects/dictobject.c

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7213,7 +7213,7 @@ PyObject_GenericGetDict(PyObject *obj, void *context)
72137213
}
72147214

72157215
int
7216-
_PyObjectDict_SetItem(PyTypeObject *tp, PyObject **dictptr,
7216+
_PyObjectDict_SetItem(PyTypeObject *tp, PyObject *obj, PyObject **dictptr,
72177217
PyObject *key, PyObject *value)
72187218
{
72197219
PyObject *dict;
@@ -7222,37 +7222,36 @@ _PyObjectDict_SetItem(PyTypeObject *tp, PyObject **dictptr,
72227222
PyInterpreterState *interp = _PyInterpreterState_GET();
72237223

72247224
assert(dictptr != NULL);
7225-
if ((tp->tp_flags & Py_TPFLAGS_HEAPTYPE) && (cached = CACHED_KEYS(tp))) {
7226-
assert(dictptr != NULL);
7225+
dict = *dictptr;
7226+
if (dict == NULL) {
7227+
#ifdef Py_GIL_DISABLED
7228+
Py_BEGIN_CRITICAL_SECTION(obj);
72277229
dict = *dictptr;
7228-
if (dict == NULL) {
7230+
if (dict != NULL) {
7231+
goto done;
7232+
}
7233+
#endif
7234+
if ((tp->tp_flags & Py_TPFLAGS_HEAPTYPE) && (cached = CACHED_KEYS(tp))) {
72297235
assert(!_PyType_HasFeature(tp, Py_TPFLAGS_INLINE_VALUES));
72307236
dictkeys_incref(cached);
72317237
dict = new_dict_with_shared_keys(interp, cached);
7232-
if (dict == NULL)
7233-
return -1;
7234-
*dictptr = dict;
7235-
}
7236-
if (value == NULL) {
7237-
res = PyDict_DelItem(dict, key);
72387238
}
72397239
else {
7240-
res = PyDict_SetItem(dict, key, value);
7241-
}
7242-
} else {
7243-
dict = *dictptr;
7244-
if (dict == NULL) {
72457240
dict = PyDict_New();
7246-
if (dict == NULL)
7247-
return -1;
7248-
*dictptr = dict;
72497241
}
7250-
if (value == NULL) {
7251-
res = PyDict_DelItem(dict, key);
7252-
} else {
7253-
res = PyDict_SetItem(dict, key, value);
7242+
*dictptr = dict;
7243+
#ifdef Py_GIL_DISABLED
7244+
done:
7245+
Py_END_CRITICAL_SECTION();
7246+
#endif
7247+
if (dict == NULL) {
7248+
return -1;
72547249
}
72557250
}
7251+
7252+
Py_BEGIN_CRITICAL_SECTION(dict);
7253+
res = set_or_del_lock_held((PyDictObject *)dict, key, value);
7254+
Py_END_CRITICAL_SECTION();
72567255
ASSERT_CONSISTENT(dict);
72577256
return res;
72587257
}

Objects/object.c

Lines changed: 1 addition & 1 deletion

0 commit comments

Comments
 (0)