Skip to content

Commit 77632f0

Browse files
authored
gh-141510: Avoid critical section on frozendict copy (#145920)
1 parent e6b9a14 commit 77632f0

File tree

1 file changed

+23
-8
lines changed

1 file changed

+23
-8
lines changed

Objects/dictobject.c

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -968,7 +968,9 @@ clone_combined_dict_keys(PyDictObject *orig)
968968
assert(orig->ma_keys != Py_EMPTY_KEYS);
969969
assert(orig->ma_keys->dk_refcnt == 1);
970970

971-
ASSERT_DICT_LOCKED(orig);
971+
if (!PyFrozenDict_Check(orig)) {
972+
ASSERT_DICT_LOCKED(orig);
973+
}
972974

973975
size_t keys_size = _PyDict_KeysSize(orig->ma_keys);
974976
PyDictKeysObject *keys = PyMem_Malloc(keys_size);
@@ -4322,7 +4324,10 @@ copy_lock_held(PyObject *o, int as_frozendict)
43224324
PyObject *copy;
43234325
PyDictObject *mp;
43244326

4325-
ASSERT_DICT_LOCKED(o);
4327+
// frozendict is immutable and so doesn't need critical section
4328+
if (!PyFrozenDict_Check(o)) {
4329+
ASSERT_DICT_LOCKED(o);
4330+
}
43264331

43274332
mp = (PyDictObject *)o;
43284333
if (mp->ma_used == 0) {
@@ -4445,9 +4450,14 @@ anydict_copy(PyObject *o)
44454450
assert(PyAnyDict_Check(o));
44464451

44474452
PyObject *res;
4448-
Py_BEGIN_CRITICAL_SECTION(o);
4449-
res = copy_lock_held(o, PyFrozenDict_Check(o));
4450-
Py_END_CRITICAL_SECTION();
4453+
if (PyFrozenDict_Check(o)) {
4454+
res = copy_lock_held(o, 1);
4455+
}
4456+
else {
4457+
Py_BEGIN_CRITICAL_SECTION(o);
4458+
res = copy_lock_held(o, 0);
4459+
Py_END_CRITICAL_SECTION();
4460+
}
44514461
return res;
44524462
}
44534463

@@ -4459,9 +4469,14 @@ _PyDict_CopyAsDict(PyObject *o)
44594469
assert(PyAnyDict_Check(o));
44604470

44614471
PyObject *res;
4462-
Py_BEGIN_CRITICAL_SECTION(o);
4463-
res = copy_lock_held(o, 0);
4464-
Py_END_CRITICAL_SECTION();
4472+
if (PyFrozenDict_Check(o)) {
4473+
res = copy_lock_held(o, 0);
4474+
}
4475+
else {
4476+
Py_BEGIN_CRITICAL_SECTION(o);
4477+
res = copy_lock_held(o, 0);
4478+
Py_END_CRITICAL_SECTION();
4479+
}
44654480
return res;
44664481
}
44674482

0 commit comments

Comments
 (0)