From 7e7bef56044874d9c1224915a7b1eaf74bd32db0 Mon Sep 17 00:00:00 2001 From: Tomasz Pytel Date: Mon, 17 Feb 2025 10:25:17 -0500 Subject: [PATCH 1/6] gh-129107: two cases where second operand needs lock --- Lib/test/test_bytes.py | 12 ++++++++++++ Objects/bytearrayobject.c | 23 ++++++++++++++++++----- 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/Lib/test/test_bytes.py b/Lib/test/test_bytes.py index 9ec5f4525c5d32..5af2e401aef185 100644 --- a/Lib/test/test_bytes.py +++ b/Lib/test/test_bytes.py @@ -2380,12 +2380,22 @@ def ass_subscript(b, a): # MODIFIES! b.wait() a[:] = c + def ass_subscript2(b, a, c): # MODIFIES! + b.wait() + a[:] = c + assert b'\xdd' not in a + def mod(b, a): c = tuple(range(4096)) b.wait() try: a % c except TypeError: pass + def mod2(b, a, c): + b.wait() + d = a % c + assert b'\xdd' not in d + def repr_(b, a): b.wait() repr(a) @@ -2506,7 +2516,9 @@ def check(funcs, a=None, *args): check([clear] + [contains] * 10) check([clear] + [subscript] * 10) + check([clear2] + [ass_subscript2] * 10, None, bytearray(b'0' * 0x400000)) check([clear] + [mod] * 10, bytearray(b'%d' * 4096)) + check([clear2] + [mod2] * 10, bytearray(b'%s'), bytearray(b'0' * 0x400000)) check([clear] + [capitalize] * 10, bytearray(b'a' * 0x40000)) check([clear] + [center] * 10, bytearray(b'a' * 0x40000)) diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index 30cc05a1280dd1..331724d6aed78f 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -707,6 +707,11 @@ static int bytearray_ass_subscript_lock_held(PyObject *op, PyObject *index, PyObject *values) { _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(op); +#ifdef Py_DEBUG + if (values != NULL) { + _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(values); + } +#endif PyByteArrayObject *self = _PyByteArray_CAST(op); Py_ssize_t start, stop, step, slicelen; char *buf = PyByteArray_AS_STRING(self); @@ -864,9 +869,16 @@ static int bytearray_ass_subscript(PyObject *op, PyObject *index, PyObject *values) { int ret; - Py_BEGIN_CRITICAL_SECTION(op); - ret = bytearray_ass_subscript_lock_held(op, index, values); - Py_END_CRITICAL_SECTION(); + if (values != NULL) { + Py_BEGIN_CRITICAL_SECTION2(op, values); + ret = bytearray_ass_subscript_lock_held(op, index, values); + Py_END_CRITICAL_SECTION2(); + } + else { + Py_BEGIN_CRITICAL_SECTION(op); + ret = bytearray_ass_subscript_lock_held(op, index, values); + Py_END_CRITICAL_SECTION(); + } return ret; } @@ -2742,6 +2754,7 @@ static PyObject * bytearray_mod_lock_held(PyObject *v, PyObject *w) { _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(v); + _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(w); if (!PyByteArray_Check(v)) Py_RETURN_NOTIMPLEMENTED; return _PyBytes_FormatEx(PyByteArray_AS_STRING(v), PyByteArray_GET_SIZE(v), w, 1); @@ -2751,9 +2764,9 @@ static PyObject * bytearray_mod(PyObject *v, PyObject *w) { PyObject *ret; - Py_BEGIN_CRITICAL_SECTION(v); + Py_BEGIN_CRITICAL_SECTION2(v, w); ret = bytearray_mod_lock_held(v, w); - Py_END_CRITICAL_SECTION(); + Py_END_CRITICAL_SECTION2(); return ret; } From 3c62f816a3692750ec42627d52c65be85b53da5b Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Mon, 17 Feb 2025 15:32:29 +0000 Subject: [PATCH 2/6] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20blu?= =?UTF-8?q?rb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../2025-02-17-15-32-26.gh-issue-129107.fPPBLw.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2025-02-17-15-32-26.gh-issue-129107.fPPBLw.rst diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-02-17-15-32-26.gh-issue-129107.fPPBLw.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-02-17-15-32-26.gh-issue-129107.fPPBLw.rst new file mode 100644 index 00000000000000..6589670e8c360e --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2025-02-17-15-32-26.gh-issue-129107.fPPBLw.rst @@ -0,0 +1 @@ +Fix two more :class:`bytearray` functions for :term:`free-threading`. From d36b4aa714c77fcdb775ce02a0b499ba41edb6ac Mon Sep 17 00:00:00 2001 From: Tomasz Pytel Date: Mon, 17 Feb 2025 10:45:15 -0500 Subject: [PATCH 3/6] lock second operand in bytearray_iconcat as well --- .../2025-02-17-15-32-26.gh-issue-129107.fPPBLw.rst | 2 +- Objects/bytearrayobject.c | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-02-17-15-32-26.gh-issue-129107.fPPBLw.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-02-17-15-32-26.gh-issue-129107.fPPBLw.rst index 6589670e8c360e..ca921f4d6c8893 100644 --- a/Misc/NEWS.d/next/Core_and_Builtins/2025-02-17-15-32-26.gh-issue-129107.fPPBLw.rst +++ b/Misc/NEWS.d/next/Core_and_Builtins/2025-02-17-15-32-26.gh-issue-129107.fPPBLw.rst @@ -1 +1 @@ -Fix two more :class:`bytearray` functions for :term:`free-threading`. +Fix two more :class:`bytearray` functions for :term:`free threading`. diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index 331724d6aed78f..f0d9a09a667cff 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -329,6 +329,7 @@ static PyObject * bytearray_iconcat_lock_held(PyObject *op, PyObject *other) { _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(op); + _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(other); PyByteArrayObject *self = _PyByteArray_CAST(op); Py_buffer vo; @@ -358,9 +359,9 @@ static PyObject * bytearray_iconcat(PyObject *op, PyObject *other) { PyObject *ret; - Py_BEGIN_CRITICAL_SECTION(op); + Py_BEGIN_CRITICAL_SECTION2(op, other); ret = bytearray_iconcat_lock_held(op, other); - Py_END_CRITICAL_SECTION(); + Py_END_CRITICAL_SECTION2(); return ret; } From 2f923119a2db0cc81641e65bce8d71cc6115734d Mon Sep 17 00:00:00 2001 From: Tomasz Pytel Date: Sun, 23 Feb 2025 11:06:37 -0500 Subject: [PATCH 4/6] remove unnecessary guard --- Objects/bytearrayobject.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index f0d9a09a667cff..f15f61d1995563 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -708,11 +708,9 @@ static int bytearray_ass_subscript_lock_held(PyObject *op, PyObject *index, PyObject *values) { _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(op); -#ifdef Py_DEBUG if (values != NULL) { _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(values); } -#endif PyByteArrayObject *self = _PyByteArray_CAST(op); Py_ssize_t start, stop, step, slicelen; char *buf = PyByteArray_AS_STRING(self); From fe15cf3913f0180b0bd0bb2ec99aaaff75fd3646 Mon Sep 17 00:00:00 2001 From: Tomasz Pytel Date: Mon, 24 Feb 2025 16:46:26 -0500 Subject: [PATCH 5/6] bytearray_ass_subscript use PyByteArray_Check() --- Objects/bytearrayobject.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index f15f61d1995563..6ae951ad6d1f68 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -329,7 +329,6 @@ static PyObject * bytearray_iconcat_lock_held(PyObject *op, PyObject *other) { _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(op); - _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(other); PyByteArrayObject *self = _PyByteArray_CAST(op); Py_buffer vo; @@ -359,9 +358,9 @@ static PyObject * bytearray_iconcat(PyObject *op, PyObject *other) { PyObject *ret; - Py_BEGIN_CRITICAL_SECTION2(op, other); + Py_BEGIN_CRITICAL_SECTION(op); ret = bytearray_iconcat_lock_held(op, other); - Py_END_CRITICAL_SECTION2(); + Py_END_CRITICAL_SECTION(); return ret; } @@ -708,9 +707,6 @@ static int bytearray_ass_subscript_lock_held(PyObject *op, PyObject *index, PyObject *values) { _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(op); - if (values != NULL) { - _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(values); - } PyByteArrayObject *self = _PyByteArray_CAST(op); Py_ssize_t start, stop, step, slicelen; char *buf = PyByteArray_AS_STRING(self); @@ -868,7 +864,7 @@ static int bytearray_ass_subscript(PyObject *op, PyObject *index, PyObject *values) { int ret; - if (values != NULL) { + if (values != NULL && PyByteArray_Check(values)) { Py_BEGIN_CRITICAL_SECTION2(op, values); ret = bytearray_ass_subscript_lock_held(op, index, values); Py_END_CRITICAL_SECTION2(); From 9b06d82e4057c5ea696cb636a554d58f25ed068c Mon Sep 17 00:00:00 2001 From: Tomasz Pytel Date: Wed, 26 Feb 2025 13:07:27 -0500 Subject: [PATCH 6/6] bytearray_mod conditional lock second arg --- Objects/bytearrayobject.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index 6ae951ad6d1f68..ec83cdbb95ac82 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -2749,7 +2749,6 @@ static PyObject * bytearray_mod_lock_held(PyObject *v, PyObject *w) { _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(v); - _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(w); if (!PyByteArray_Check(v)) Py_RETURN_NOTIMPLEMENTED; return _PyBytes_FormatEx(PyByteArray_AS_STRING(v), PyByteArray_GET_SIZE(v), w, 1); @@ -2759,9 +2758,16 @@ static PyObject * bytearray_mod(PyObject *v, PyObject *w) { PyObject *ret; - Py_BEGIN_CRITICAL_SECTION2(v, w); - ret = bytearray_mod_lock_held(v, w); - Py_END_CRITICAL_SECTION2(); + if (PyByteArray_Check(w)) { + Py_BEGIN_CRITICAL_SECTION2(v, w); + ret = bytearray_mod_lock_held(v, w); + Py_END_CRITICAL_SECTION2(); + } + else { + Py_BEGIN_CRITICAL_SECTION(v); + ret = bytearray_mod_lock_held(v, w); + Py_END_CRITICAL_SECTION(); + } return ret; }