]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-112087: Update list impl to be thread-safe with manual CS (gh-113863)
authorDonghee Na <donghee.na@python.org>
Tue, 16 Jan 2024 00:11:14 +0000 (09:11 +0900)
committerGitHub <noreply@github.com>
Tue, 16 Jan 2024 00:11:14 +0000 (09:11 +0900)
Objects/clinic/listobject.c.h
Objects/listobject.c

index cf6f7449df5e1d70ad9c93c4661e9abcdf30152f..a61550a49b66fc8568fc58a97210a041e598fbae 100644 (file)
@@ -92,7 +92,13 @@ list_copy_impl(PyListObject *self);
 static PyObject *
 list_copy(PyListObject *self, PyObject *Py_UNUSED(ignored))
 {
-    return list_copy_impl(self);
+    PyObject *return_value = NULL;
+
+    Py_BEGIN_CRITICAL_SECTION(self);
+    return_value = list_copy_impl(self);
+    Py_END_CRITICAL_SECTION();
+
+    return return_value;
 }
 
 PyDoc_STRVAR(list_append__doc__,
@@ -104,6 +110,21 @@ PyDoc_STRVAR(list_append__doc__,
 #define LIST_APPEND_METHODDEF    \
     {"append", (PyCFunction)list_append, METH_O, list_append__doc__},
 
+static PyObject *
+list_append_impl(PyListObject *self, PyObject *object);
+
+static PyObject *
+list_append(PyListObject *self, PyObject *object)
+{
+    PyObject *return_value = NULL;
+
+    Py_BEGIN_CRITICAL_SECTION(self);
+    return_value = list_append_impl(self, object);
+    Py_END_CRITICAL_SECTION();
+
+    return return_value;
+}
+
 PyDoc_STRVAR(py_list_extend__doc__,
 "extend($self, iterable, /)\n"
 "--\n"
@@ -113,6 +134,21 @@ PyDoc_STRVAR(py_list_extend__doc__,
 #define PY_LIST_EXTEND_METHODDEF    \
     {"extend", (PyCFunction)py_list_extend, METH_O, py_list_extend__doc__},
 
+static PyObject *
+py_list_extend_impl(PyListObject *self, PyObject *iterable);
+
+static PyObject *
+py_list_extend(PyListObject *self, PyObject *iterable)
+{
+    PyObject *return_value = NULL;
+
+    Py_BEGIN_CRITICAL_SECTION2(self, iterable);
+    return_value = py_list_extend_impl(self, iterable);
+    Py_END_CRITICAL_SECTION2();
+
+    return return_value;
+}
+
 PyDoc_STRVAR(list_pop__doc__,
 "pop($self, index=-1, /)\n"
 "--\n"
@@ -416,4 +452,4 @@ list___reversed__(PyListObject *self, PyObject *Py_UNUSED(ignored))
 {
     return list___reversed___impl(self);
 }
-/*[clinic end generated code: output=3c9f24fd3212b18b input=a9049054013a1b77]*/
+/*[clinic end generated code: output=26dfb2c9846348f9 input=a9049054013a1b77]*/
index 288c704be9842a4431a18432ea897e45e65a37b8..79ef8f532fbb98b10af7cc3a3606c355ea5628e5 100644 (file)
@@ -263,15 +263,22 @@ PyList_SetItem(PyObject *op, Py_ssize_t i,
         PyErr_BadInternalCall();
         return -1;
     }
-    if (!valid_index(i, Py_SIZE(op))) {
+    int ret;
+    PyListObject *self = ((PyListObject *)op);
+    Py_BEGIN_CRITICAL_SECTION(self);
+    if (!valid_index(i, Py_SIZE(self))) {
         Py_XDECREF(newitem);
         PyErr_SetString(PyExc_IndexError,
                         "list assignment index out of range");
-        return -1;
+        ret = -1;
+        goto end;
     }
-    p = ((PyListObject *)op) -> ob_item + i;
+    p = self->ob_item + i;
     Py_XSETREF(*p, newitem);
-    return 0;
+    ret = 0;
+end:
+    Py_END_CRITICAL_SECTION();
+    return ret;
 }
 
 static int
@@ -309,7 +316,12 @@ PyList_Insert(PyObject *op, Py_ssize_t where, PyObject *newitem)
         PyErr_BadInternalCall();
         return -1;
     }
-    return ins1((PyListObject *)op, where, newitem);
+    PyListObject *self = (PyListObject *)op;
+    int err;
+    Py_BEGIN_CRITICAL_SECTION(self);
+    err = ins1(self, where, newitem);
+    Py_END_CRITICAL_SECTION();
+    return err;
 }
 
 /* internal, used by _PyList_AppendTakeRef */
@@ -804,9 +816,13 @@ static PyObject *
 list_insert_impl(PyListObject *self, Py_ssize_t index, PyObject *object)
 /*[clinic end generated code: output=7f35e32f60c8cb78 input=b1987ca998a4ae2d]*/
 {
-    if (ins1(self, index, object) == 0)
-        Py_RETURN_NONE;
-    return NULL;
+    PyObject *ret = Py_None;
+    Py_BEGIN_CRITICAL_SECTION(self);
+    if (ins1(self, index, object) < 0) {
+        ret = NULL;
+    }
+    Py_END_CRITICAL_SECTION();
+    return ret;
 }
 
 /*[clinic input]
@@ -825,6 +841,7 @@ py_list_clear_impl(PyListObject *self)
 }
 
 /*[clinic input]
+@critical_section
 list.copy
 
 Return a shallow copy of the list.
@@ -832,12 +849,13 @@ Return a shallow copy of the list.
 
 static PyObject *
 list_copy_impl(PyListObject *self)
-/*[clinic end generated code: output=ec6b72d6209d418e input=6453ab159e84771f]*/
+/*[clinic end generated code: output=ec6b72d6209d418e input=81c54b0c7bb4f73d]*/
 {
     return list_slice(self, 0, Py_SIZE(self));
 }
 
 /*[clinic input]
+@critical_section
 list.append
 
      object: object
@@ -847,8 +865,8 @@ Append object to the end of the list.
 [clinic start generated code]*/
 
 static PyObject *
-list_append(PyListObject *self, PyObject *object)
-/*[clinic end generated code: output=7c096003a29c0eae input=43a3fe48a7066e91]*/
+list_append_impl(PyListObject *self, PyObject *object)
+/*[clinic end generated code: output=78423561d92ed405 input=122b0853de54004f]*/
 {
     if (_PyList_AppendTakeRef(self, Py_NewRef(object)) < 0) {
         return NULL;
@@ -1006,6 +1024,7 @@ _PyList_Extend(PyListObject *self, PyObject *iterable)
 
 
 /*[clinic input]
+@critical_section self iterable
 list.extend as py_list_extend
 
      iterable: object
@@ -1015,8 +1034,8 @@ Extend list by appending elements from the iterable.
 [clinic start generated code]*/
 
 static PyObject *
-py_list_extend(PyListObject *self, PyObject *iterable)
-/*[clinic end generated code: output=b8e0bff0ceae2abd input=9a8376a8633ed3ba]*/
+py_list_extend_impl(PyListObject *self, PyObject *iterable)
+/*[clinic end generated code: output=a2f115ceace2c845 input=1d42175414e1a5f3]*/
 {
     return _PyList_Extend(self, iterable);
 }
@@ -2612,8 +2631,11 @@ PyList_Reverse(PyObject *v)
         PyErr_BadInternalCall();
         return -1;
     }
-    if (Py_SIZE(self) > 1)
+    Py_BEGIN_CRITICAL_SECTION(self);
+    if (Py_SIZE(self) > 1) {
         reverse_slice(self->ob_item, self->ob_item + Py_SIZE(self));
+    }
+    Py_END_CRITICAL_SECTION()
     return 0;
 }
 
@@ -2624,7 +2646,12 @@ PyList_AsTuple(PyObject *v)
         PyErr_BadInternalCall();
         return NULL;
     }
-    return _PyTuple_FromArray(((PyListObject *)v)->ob_item, Py_SIZE(v));
+    PyObject *ret;
+    PyListObject *self = (PyListObject *)v;
+    Py_BEGIN_CRITICAL_SECTION(self);
+    ret = _PyTuple_FromArray(self->ob_item, Py_SIZE(v));
+    Py_END_CRITICAL_SECTION();
+    return ret;
 }
 
 PyObject *
@@ -2773,7 +2800,7 @@ list_traverse(PyObject *self, visitproc visit, void *arg)
 }
 
 static PyObject *
-list_richcompare(PyObject *v, PyObject *w, int op)
+list_richcompare_impl(PyObject *v, PyObject *w, int op)
 {
     PyListObject *vl, *wl;
     Py_ssize_t i;
@@ -2828,6 +2855,16 @@ list_richcompare(PyObject *v, PyObject *w, int op)
     return PyObject_RichCompare(vl->ob_item[i], wl->ob_item[i], op);
 }
 
+static PyObject *
+list_richcompare(PyObject *v, PyObject *w, int op)
+{
+    PyObject *ret;
+    Py_BEGIN_CRITICAL_SECTION2(v, w);
+    ret = list_richcompare_impl(v, w, op);
+    Py_END_CRITICAL_SECTION2()
+    return ret;
+}
+
 /*[clinic input]
 list.__init__