Skip to content

Commit 836ad73

Browse files
committed
gh-141510: Avoid critical section on frozendict copy
1 parent 962fb87 commit 836ad73

File tree

1 file changed

+20
-7
lines changed

1 file changed

+20
-7
lines changed

Objects/dictobject.c

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4322,7 +4322,10 @@ copy_lock_held(PyObject *o, int as_frozendict)
43224322
PyObject *copy;
43234323
PyDictObject *mp;
43244324

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

43274330
mp = (PyDictObject *)o;
43284331
if (mp->ma_used == 0) {
@@ -4445,9 +4448,14 @@ anydict_copy(PyObject *o)
44454448
assert(PyAnyDict_Check(o));
44464449

44474450
PyObject *res;
4448-
Py_BEGIN_CRITICAL_SECTION(o);
4449-
res = copy_lock_held(o, PyFrozenDict_Check(o));
4450-
Py_END_CRITICAL_SECTION();
4451+
if (PyFrozenDict_Check(o)) {
4452+
res = copy_lock_held(o, 1);
4453+
}
4454+
else {
4455+
Py_BEGIN_CRITICAL_SECTION(o);
4456+
res = copy_lock_held(o, 0);
4457+
Py_END_CRITICAL_SECTION();
4458+
}
44514459
return res;
44524460
}
44534461

@@ -4459,9 +4467,14 @@ _PyDict_CopyAsDict(PyObject *o)
44594467
assert(PyAnyDict_Check(o));
44604468

44614469
PyObject *res;
4462-
Py_BEGIN_CRITICAL_SECTION(o);
4463-
res = copy_lock_held(o, 0);
4464-
Py_END_CRITICAL_SECTION();
4470+
if (PyFrozenDict_Check(o)) {
4471+
res = copy_lock_held(o, 0);
4472+
}
4473+
else {
4474+
Py_BEGIN_CRITICAL_SECTION(o);
4475+
res = copy_lock_held(o, 0);
4476+
Py_END_CRITICAL_SECTION();
4477+
}
44654478
return res;
44664479
}
44674480

0 commit comments

Comments
 (0)