Skip to content

Commit 89b08a6

Browse files
corona10kulikjak
authored andcommitted
pythongh-112087: Update list impl to be thread-safe with manual CS (pythongh-113863)
1 parent ed5889d commit 89b08a6

File tree

2 files changed

+91
-18
lines changed

2 files changed

+91
-18
lines changed

Objects/clinic/listobject.c.h

+38-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Objects/listobject.c

+53-16
Original file line numberDiff line numberDiff line change
@@ -263,15 +263,22 @@ PyList_SetItem(PyObject *op, Py_ssize_t i,
263263
PyErr_BadInternalCall();
264264
return -1;
265265
}
266-
if (!valid_index(i, Py_SIZE(op))) {
266+
int ret;
267+
PyListObject *self = ((PyListObject *)op);
268+
Py_BEGIN_CRITICAL_SECTION(self);
269+
if (!valid_index(i, Py_SIZE(self))) {
267270
Py_XDECREF(newitem);
268271
PyErr_SetString(PyExc_IndexError,
269272
"list assignment index out of range");
270-
return -1;
273+
ret = -1;
274+
goto end;
271275
}
272-
p = ((PyListObject *)op) -> ob_item + i;
276+
p = self->ob_item + i;
273277
Py_XSETREF(*p, newitem);
274-
return 0;
278+
ret = 0;
279+
end:
280+
Py_END_CRITICAL_SECTION();
281+
return ret;
275282
}
276283

277284
static int
@@ -309,7 +316,12 @@ PyList_Insert(PyObject *op, Py_ssize_t where, PyObject *newitem)
309316
PyErr_BadInternalCall();
310317
return -1;
311318
}
312-
return ins1((PyListObject *)op, where, newitem);
319+
PyListObject *self = (PyListObject *)op;
320+
int err;
321+
Py_BEGIN_CRITICAL_SECTION(self);
322+
err = ins1(self, where, newitem);
323+
Py_END_CRITICAL_SECTION();
324+
return err;
313325
}
314326

315327
/* internal, used by _PyList_AppendTakeRef */
@@ -804,9 +816,13 @@ static PyObject *
804816
list_insert_impl(PyListObject *self, Py_ssize_t index, PyObject *object)
805817
/*[clinic end generated code: output=7f35e32f60c8cb78 input=b1987ca998a4ae2d]*/
806818
{
807-
if (ins1(self, index, object) == 0)
808-
Py_RETURN_NONE;
809-
return NULL;
819+
PyObject *ret = Py_None;
820+
Py_BEGIN_CRITICAL_SECTION(self);
821+
if (ins1(self, index, object) < 0) {
822+
ret = NULL;
823+
}
824+
Py_END_CRITICAL_SECTION();
825+
return ret;
810826
}
811827

812828
/*[clinic input]
@@ -825,19 +841,21 @@ py_list_clear_impl(PyListObject *self)
825841
}
826842

827843
/*[clinic input]
844+
@critical_section
828845
list.copy
829846
830847
Return a shallow copy of the list.
831848
[clinic start generated code]*/
832849

833850
static PyObject *
834851
list_copy_impl(PyListObject *self)
835-
/*[clinic end generated code: output=ec6b72d6209d418e input=6453ab159e84771f]*/
852+
/*[clinic end generated code: output=ec6b72d6209d418e input=81c54b0c7bb4f73d]*/
836853
{
837854
return list_slice(self, 0, Py_SIZE(self));
838855
}
839856

840857
/*[clinic input]
858+
@critical_section
841859
list.append
842860
843861
object: object
@@ -847,8 +865,8 @@ Append object to the end of the list.
847865
[clinic start generated code]*/
848866

849867
static PyObject *
850-
list_append(PyListObject *self, PyObject *object)
851-
/*[clinic end generated code: output=7c096003a29c0eae input=43a3fe48a7066e91]*/
868+
list_append_impl(PyListObject *self, PyObject *object)
869+
/*[clinic end generated code: output=78423561d92ed405 input=122b0853de54004f]*/
852870
{
853871
if (_PyList_AppendTakeRef(self, Py_NewRef(object)) < 0) {
854872
return NULL;
@@ -1006,6 +1024,7 @@ _PyList_Extend(PyListObject *self, PyObject *iterable)
10061024

10071025

10081026
/*[clinic input]
1027+
@critical_section self iterable
10091028
list.extend as py_list_extend
10101029
10111030
iterable: object
@@ -1015,8 +1034,8 @@ Extend list by appending elements from the iterable.
10151034
[clinic start generated code]*/
10161035

10171036
static PyObject *
1018-
py_list_extend(PyListObject *self, PyObject *iterable)
1019-
/*[clinic end generated code: output=b8e0bff0ceae2abd input=9a8376a8633ed3ba]*/
1037+
py_list_extend_impl(PyListObject *self, PyObject *iterable)
1038+
/*[clinic end generated code: output=a2f115ceace2c845 input=1d42175414e1a5f3]*/
10201039
{
10211040
return _PyList_Extend(self, iterable);
10221041
}
@@ -2612,8 +2631,11 @@ PyList_Reverse(PyObject *v)
26122631
PyErr_BadInternalCall();
26132632
return -1;
26142633
}
2615-
if (Py_SIZE(self) > 1)
2634+
Py_BEGIN_CRITICAL_SECTION(self);
2635+
if (Py_SIZE(self) > 1) {
26162636
reverse_slice(self->ob_item, self->ob_item + Py_SIZE(self));
2637+
}
2638+
Py_END_CRITICAL_SECTION()
26172639
return 0;
26182640
}
26192641

@@ -2624,7 +2646,12 @@ PyList_AsTuple(PyObject *v)
26242646
PyErr_BadInternalCall();
26252647
return NULL;
26262648
}
2627-
return _PyTuple_FromArray(((PyListObject *)v)->ob_item, Py_SIZE(v));
2649+
PyObject *ret;
2650+
PyListObject *self = (PyListObject *)v;
2651+
Py_BEGIN_CRITICAL_SECTION(self);
2652+
ret = _PyTuple_FromArray(self->ob_item, Py_SIZE(v));
2653+
Py_END_CRITICAL_SECTION();
2654+
return ret;
26282655
}
26292656

26302657
PyObject *
@@ -2773,7 +2800,7 @@ list_traverse(PyObject *self, visitproc visit, void *arg)
27732800
}
27742801

27752802
static PyObject *
2776-
list_richcompare(PyObject *v, PyObject *w, int op)
2803+
list_richcompare_impl(PyObject *v, PyObject *w, int op)
27772804
{
27782805
PyListObject *vl, *wl;
27792806
Py_ssize_t i;
@@ -2828,6 +2855,16 @@ list_richcompare(PyObject *v, PyObject *w, int op)
28282855
return PyObject_RichCompare(vl->ob_item[i], wl->ob_item[i], op);
28292856
}
28302857

2858+
static PyObject *
2859+
list_richcompare(PyObject *v, PyObject *w, int op)
2860+
{
2861+
PyObject *ret;
2862+
Py_BEGIN_CRITICAL_SECTION2(v, w);
2863+
ret = list_richcompare_impl(v, w, op);
2864+
Py_END_CRITICAL_SECTION2()
2865+
return ret;
2866+
}
2867+
28312868
/*[clinic input]
28322869
list.__init__
28332870

0 commit comments

Comments
 (0)