Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gh-112087: Update list impl to be thread-safe with manual CS #113863

Merged
merged 3 commits into from
Jan 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 38 additions & 2 deletions Objects/clinic/listobject.c.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

69 changes: 53 additions & 16 deletions Objects/listobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -267,15 +267,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);
corona10 marked this conversation as resolved.
Show resolved Hide resolved
return 0;
ret = 0;
end:
Py_END_CRITICAL_SECTION();
return ret;
}

static int
Expand Down Expand Up @@ -313,7 +320,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 */
Expand Down Expand Up @@ -812,9 +824,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]
Expand All @@ -833,19 +849,21 @@ py_list_clear_impl(PyListObject *self)
}

/*[clinic input]
@critical_section
list.copy

Return a shallow copy of the list.
[clinic start generated code]*/

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
Expand All @@ -855,8 +873,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;
Expand Down Expand Up @@ -1014,6 +1032,7 @@ _PyList_Extend(PyListObject *self, PyObject *iterable)


/*[clinic input]
@critical_section self iterable
list.extend as py_list_extend

iterable: object
Expand All @@ -1023,8 +1042,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);
}
Expand Down Expand Up @@ -2620,8 +2639,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;
}

Expand All @@ -2632,7 +2654,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;
corona10 marked this conversation as resolved.
Show resolved Hide resolved
Py_BEGIN_CRITICAL_SECTION(self);
ret = _PyTuple_FromArray(self->ob_item, Py_SIZE(v));
Py_END_CRITICAL_SECTION();
return ret;
}

PyObject *
Expand Down Expand Up @@ -2781,7 +2808,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;
Expand Down Expand Up @@ -2836,6 +2863,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__

Expand Down
Loading