From 9ef7a2bb198aabf0b6f712ef7c37ceae7ff7641a Mon Sep 17 00:00:00 2001 From: sobolevn Date: Wed, 5 Feb 2025 11:31:22 +0300 Subject: [PATCH 1/2] gh-129643: Fix `PyList_Insert` in free-threading builds --- .../2025-02-05-11-29-52.gh-issue-129643.4mGzvg.rst | 1 + Objects/listobject.c | 6 ++---- 2 files changed, 3 insertions(+), 4 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2025-02-05-11-29-52.gh-issue-129643.4mGzvg.rst diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-02-05-11-29-52.gh-issue-129643.4mGzvg.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-02-05-11-29-52.gh-issue-129643.4mGzvg.rst new file mode 100644 index 00000000000000..420e1fb9781ff3 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2025-02-05-11-29-52.gh-issue-129643.4mGzvg.rst @@ -0,0 +1 @@ +Fix thread safety of :c:func:`PyList_Insert` in free-threading builds. diff --git a/Objects/listobject.c b/Objects/listobject.c index 86fa2149556463..fdff8e8d5d15f5 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -447,7 +447,6 @@ static int ins1(PyListObject *self, Py_ssize_t where, PyObject *v) { Py_ssize_t i, n = Py_SIZE(self); - PyObject **items; if (v == NULL) { PyErr_BadInternalCall(); return -1; @@ -464,10 +463,9 @@ ins1(PyListObject *self, Py_ssize_t where, PyObject *v) } if (where > n) where = n; - items = self->ob_item; for (i = n; --i >= where; ) - items[i+1] = items[i]; - items[where] = Py_NewRef(v); + FT_ATOMIC_STORE_PTR_RELEASE(self->ob_item[i+1], self->ob_item[i]); + FT_ATOMIC_STORE_PTR_RELEASE(self->ob_item[where], Py_NewRef(v)); return 0; } From 2c12e9231599874365b6e6741b4414f7ac412afd Mon Sep 17 00:00:00 2001 From: sobolevn Date: Thu, 6 Feb 2025 02:32:53 +0300 Subject: [PATCH 2/2] Address review --- Objects/listobject.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Objects/listobject.c b/Objects/listobject.c index fdff8e8d5d15f5..120e353b709e7b 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -447,6 +447,7 @@ static int ins1(PyListObject *self, Py_ssize_t where, PyObject *v) { Py_ssize_t i, n = Py_SIZE(self); + PyObject **items; if (v == NULL) { PyErr_BadInternalCall(); return -1; @@ -463,9 +464,10 @@ ins1(PyListObject *self, Py_ssize_t where, PyObject *v) } if (where > n) where = n; + items = self->ob_item; for (i = n; --i >= where; ) - FT_ATOMIC_STORE_PTR_RELEASE(self->ob_item[i+1], self->ob_item[i]); - FT_ATOMIC_STORE_PTR_RELEASE(self->ob_item[where], Py_NewRef(v)); + FT_ATOMIC_STORE_PTR_RELAXED(items[i+1], items[i]); + FT_ATOMIC_STORE_PTR_RELEASE(items[where], Py_NewRef(v)); return 0; }