From: Victor Stinner Date: Sat, 23 May 2026 06:57:27 +0000 (+0200) Subject: [3.15] Revert "[3.15] gh-146452: Improve locking granularity in pickle's batch_dict_e... X-Git-Tag: v3.15.0b2~91 X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=795dd3bd3500c49c6a08281a15a9472a28f416d3;p=thirdparty%2FPython%2Fcpython.git [3.15] Revert "[3.15] gh-146452: Improve locking granularity in pickle's batch_dict_exact and fix race condition (GH-150025) (#150039)" (#150262) Revert "[3.15] gh-146452: Improve locking granularity in pickle's batch_dict_exact and fix race condition (GH-150025) (#150039)" This reverts commit 66ade2861fec1d6c18998710938a1c71fde5f76b. --- diff --git a/Misc/NEWS.d/next/Library/2026-05-18-15-30-34.gh-issue-146452.RM0EVJ.rst b/Misc/NEWS.d/next/Library/2026-05-18-15-30-34.gh-issue-146452.RM0EVJ.rst deleted file mode 100644 index 66f9acf6c710..000000000000 --- a/Misc/NEWS.d/next/Library/2026-05-18-15-30-34.gh-issue-146452.RM0EVJ.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix race condition when pickling dictionaries in free threaded builds. Also -reduce critical section cover. diff --git a/Modules/_pickle.c b/Modules/_pickle.c index 15d95c658d6f..9874f9475ac0 100644 --- a/Modules/_pickle.c +++ b/Modules/_pickle.c @@ -3450,9 +3450,6 @@ batch_dict(PickleState *state, PicklerObject *self, PyObject *iter, PyObject *or * Returns 0 on success, -1 on error. * * Note that this currently doesn't work for protocol 0. - - * gh-146452: Wrap the dict iteration in a critical sections to prevent - * concurrent mutation from invalidating PyDict_Next() iteration state. */ static int batch_dict_exact(PickleState *state, PicklerObject *self, PyObject *obj) @@ -3469,24 +3466,15 @@ batch_dict_exact(PickleState *state, PicklerObject *self, PyObject *obj) assert(self->proto > 0); dict_size = PyDict_GET_SIZE(obj); + assert(dict_size); /* Write in batches of BATCHSIZE. */ Py_ssize_t total = 0; do { if (dict_size - total == 1) { - int next; - Py_BEGIN_CRITICAL_SECTION(obj); - next = PyDict_Next(obj, &ppos, &key, &value); - if (next) { - Py_INCREF(key); - Py_INCREF(value); - } - Py_END_CRITICAL_SECTION(); - if (!next) { - PyErr_SetString(PyExc_RuntimeError, - "dictionary changed size during iteration"); - goto error; - } + PyDict_Next(obj, &ppos, &key, &value); + Py_INCREF(key); + Py_INCREF(value); if (save(state, self, key, 0) < 0) { goto error; } @@ -3504,18 +3492,9 @@ batch_dict_exact(PickleState *state, PicklerObject *self, PyObject *obj) i = 0; if (_Pickler_Write(self, &mark_op, 1) < 0) return -1; - int next; - while (1) { - Py_BEGIN_CRITICAL_SECTION(obj); - next = PyDict_Next(obj, &ppos, &key, &value); - if (next) { - Py_INCREF(key); - Py_INCREF(value); - } - Py_END_CRITICAL_SECTION(); - if (!next) { - break; - } + while (PyDict_Next(obj, &ppos, &key, &value)) { + Py_INCREF(key); + Py_INCREF(value); if (save(state, self, key, 0) < 0) { goto error; }