gh-129107: fix thread safety of bytearray where two critical sections are needed (#130227)

This commit is contained in:
Tomasz Pytel 2025-02-27 09:59:58 -05:00 committed by GitHub
parent 8ba0d7bbc2
commit e85f81f430
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 33 additions and 6 deletions

View file

@ -2380,12 +2380,22 @@ class FreeThreadingTest(unittest.TestCase):
b.wait() b.wait()
a[:] = c a[:] = c
def ass_subscript2(b, a, c): # MODIFIES!
b.wait()
a[:] = c
assert b'\xdd' not in a
def mod(b, a): def mod(b, a):
c = tuple(range(4096)) c = tuple(range(4096))
b.wait() b.wait()
try: a % c try: a % c
except TypeError: pass except TypeError: pass
def mod2(b, a, c):
b.wait()
d = a % c
assert b'\xdd' not in d
def repr_(b, a): def repr_(b, a):
b.wait() b.wait()
repr(a) repr(a)
@ -2503,7 +2513,9 @@ class FreeThreadingTest(unittest.TestCase):
check([clear] + [contains] * 10) check([clear] + [contains] * 10)
check([clear] + [subscript] * 10) check([clear] + [subscript] * 10)
check([clear2] + [ass_subscript2] * 10, None, bytearray(b'0' * 0x400000))
check([clear] + [mod] * 10, bytearray(b'%d' * 4096)) 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] + [capitalize] * 10, bytearray(b'a' * 0x40000))
check([clear] + [center] * 10, bytearray(b'a' * 0x40000)) check([clear] + [center] * 10, bytearray(b'a' * 0x40000))

View file

@ -0,0 +1 @@
Fix two more :class:`bytearray` functions for :term:`free threading`.

View file

@ -864,9 +864,16 @@ static int
bytearray_ass_subscript(PyObject *op, PyObject *index, PyObject *values) bytearray_ass_subscript(PyObject *op, PyObject *index, PyObject *values)
{ {
int ret; int ret;
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();
}
else {
Py_BEGIN_CRITICAL_SECTION(op); Py_BEGIN_CRITICAL_SECTION(op);
ret = bytearray_ass_subscript_lock_held(op, index, values); ret = bytearray_ass_subscript_lock_held(op, index, values);
Py_END_CRITICAL_SECTION(); Py_END_CRITICAL_SECTION();
}
return ret; return ret;
} }
@ -2751,9 +2758,16 @@ static PyObject *
bytearray_mod(PyObject *v, PyObject *w) bytearray_mod(PyObject *v, PyObject *w)
{ {
PyObject *ret; PyObject *ret;
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); Py_BEGIN_CRITICAL_SECTION(v);
ret = bytearray_mod_lock_held(v, w); ret = bytearray_mod_lock_held(v, w);
Py_END_CRITICAL_SECTION(); Py_END_CRITICAL_SECTION();
}
return ret; return ret;
} }