Skip to content

Commit be8a6e7

Browse files
committed
pythongh-127524: Add missing locks in listobject.c
We were missing locks around some list operations in the free threading build.
1 parent c7dec02 commit be8a6e7

File tree

1 file changed

+37
-10
lines changed

1 file changed

+37
-10
lines changed

Objects/listobject.c

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include "Python.h"
44
#include "pycore_abstract.h" // _PyIndex_Check()
55
#include "pycore_ceval.h" // _PyEval_GetBuiltin()
6+
#include "pycore_critical_section.h" // _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED()
67
#include "pycore_dict.h" // _PyDictViewObject
78
#include "pycore_freelist.h" // _Py_FREELIST_FREE(), _Py_FREELIST_POP()
89
#include "pycore_pyatomic_ft_wrappers.h"
@@ -72,6 +73,8 @@ static void
7273
ensure_shared_on_resize(PyListObject *self)
7374
{
7475
#ifdef Py_GIL_DISABLED
76+
_Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(self);
77+
7578
// Ensure that the list array is freed using QSBR if we are not the
7679
// owning thread.
7780
if (!_Py_IsOwnedByCurrentThread((PyObject *)self) &&
@@ -957,10 +960,12 @@ list_ass_slice(PyListObject *a, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *v)
957960
Py_ssize_t n = PyList_GET_SIZE(a);
958961
PyObject *copy = list_slice_lock_held(a, 0, n);
959962
if (copy == NULL) {
960-
return -1;
963+
ret = -1;
964+
}
965+
else {
966+
ret = list_ass_slice_lock_held(a, ilow, ihigh, copy);
967+
Py_DECREF(copy);
961968
}
962-
ret = list_ass_slice_lock_held(a, ilow, ihigh, copy);
963-
Py_DECREF(copy);
964969
Py_END_CRITICAL_SECTION();
965970
}
966971
else if (v != NULL && PyList_CheckExact(v)) {
@@ -1437,7 +1442,9 @@ PyList_Clear(PyObject *self)
14371442
PyErr_BadInternalCall();
14381443
return -1;
14391444
}
1445+
Py_BEGIN_CRITICAL_SECTION(self);
14401446
list_clear((PyListObject*)self);
1447+
Py_END_CRITICAL_SECTION();
14411448
return 0;
14421449
}
14431450

@@ -3410,7 +3417,9 @@ list___init___impl(PyListObject *self, PyObject *iterable)
34103417

34113418
/* Empty previous contents */
34123419
if (self->ob_item != NULL) {
3420+
Py_BEGIN_CRITICAL_SECTION(self);
34133421
list_clear(self);
3422+
Py_END_CRITICAL_SECTION();
34143423
}
34153424
if (iterable != NULL) {
34163425
if (_list_extend(self, iterable) < 0) {
@@ -3583,16 +3592,18 @@ adjust_slice_indexes(PyListObject *lst,
35833592
}
35843593

35853594
static int
3586-
list_ass_subscript(PyObject* _self, PyObject* item, PyObject* value)
3595+
list_ass_subscript_lock_held(PyObject *_self, PyObject *item, PyObject *value)
35873596
{
3597+
_Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(_self);
3598+
35883599
PyListObject *self = (PyListObject *)_self;
35893600
if (_PyIndex_Check(item)) {
35903601
Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
35913602
if (i == -1 && PyErr_Occurred())
35923603
return -1;
35933604
if (i < 0)
35943605
i += PyList_GET_SIZE(self);
3595-
return list_ass_item((PyObject *)self, i, value);
3606+
return list_ass_item_lock_held(self, i, value);
35963607
}
35973608
else if (PySlice_Check(item)) {
35983609
Py_ssize_t start, stop, step;
@@ -3612,7 +3623,7 @@ list_ass_subscript(PyObject* _self, PyObject* item, PyObject* value)
36123623
step);
36133624

36143625
if (step == 1)
3615-
return list_ass_slice(self, start, stop, value);
3626+
return list_ass_slice_lock_held(self, start, stop, value);
36163627

36173628
if (slicelength <= 0)
36183629
return 0;
@@ -3678,10 +3689,8 @@ list_ass_subscript(PyObject* _self, PyObject* item, PyObject* value)
36783689

36793690
/* protect against a[::-1] = a */
36803691
if (self == (PyListObject*)value) {
3681-
Py_BEGIN_CRITICAL_SECTION(value);
3682-
seq = list_slice_lock_held((PyListObject*)value, 0,
3692+
seq = list_slice_lock_held((PyListObject *)value, 0,
36833693
Py_SIZE(value));
3684-
Py_END_CRITICAL_SECTION();
36853694
}
36863695
else {
36873696
seq = PySequence_Fast(value,
@@ -3695,7 +3704,7 @@ list_ass_subscript(PyObject* _self, PyObject* item, PyObject* value)
36953704
step);
36963705

36973706
if (step == 1) {
3698-
int res = list_ass_slice(self, start, stop, seq);
3707+
int res = list_ass_slice_lock_held(self, start, stop, seq);
36993708
Py_DECREF(seq);
37003709
return res;
37013710
}
@@ -3751,6 +3760,24 @@ list_ass_subscript(PyObject* _self, PyObject* item, PyObject* value)
37513760
}
37523761
}
37533762

3763+
static int
3764+
list_ass_subscript(PyObject *self, PyObject *item, PyObject *value)
3765+
{
3766+
int res;
3767+
#ifdef Py_GIL_DISABLED
3768+
if (PySlice_Check(item) && value != NULL && PyList_CheckExact(value)) {
3769+
Py_BEGIN_CRITICAL_SECTION2(self, value);
3770+
res = list_ass_subscript_lock_held(self, item, value);
3771+
Py_END_CRITICAL_SECTION2();
3772+
return res;
3773+
}
3774+
#endif
3775+
Py_BEGIN_CRITICAL_SECTION(self);
3776+
res = list_ass_subscript_lock_held(self, item, value);
3777+
Py_END_CRITICAL_SECTION();
3778+
return res;
3779+
}
3780+
37543781
static PyMappingMethods list_as_mapping = {
37553782
list_length,
37563783
list_subscript,

0 commit comments

Comments
 (0)