Skip to content

Commit

Permalink
Make list_ass_slice to be thread-safe(?)
Browse files Browse the repository at this point in the history
  • Loading branch information
corona10 committed Feb 23, 2024
1 parent a4bf501 commit ed192d7
Showing 1 changed file with 25 additions and 23 deletions.
48 changes: 25 additions & 23 deletions Objects/listobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -506,13 +506,13 @@ list_item(PyObject *aa, Py_ssize_t i)
}

static PyObject *
list_slice_lock_held(PyListObject *a, Py_ssize_t start, Py_ssize_t len)
list_slice_lock_held(PyListObject *a, Py_ssize_t ilow, Py_ssize_t len)
{
PyListObject *np = (PyListObject *) list_new_prealloc(len);
if (np == NULL) {
return NULL;
}
PyObject **src = a->ob_item + start;
PyObject **src = a->ob_item + ilow;
PyObject **dest = np->ob_item;
for (Py_ssize_t i = 0; i < len; i++) {
PyObject *v = src[i];
Expand All @@ -525,25 +525,11 @@ list_slice_lock_held(PyListObject *a, Py_ssize_t start, Py_ssize_t len)
static PyObject *
list_slice(PyListObject *a, Py_ssize_t ilow, Py_ssize_t ihigh)
{
PyListObject *np;
PyObject **src, **dest;
Py_ssize_t i, len;
len = ihigh - ilow;
Py_ssize_t len = ihigh - ilow;
if (len <= 0) {
return PyList_New(0);
}
np = (PyListObject *) list_new_prealloc(len);
if (np == NULL)
return NULL;

src = a->ob_item + ilow;
dest = np->ob_item;
for (i = 0; i < len; i++) {
PyObject *v = src[i];
dest[i] = Py_NewRef(v);
}
Py_SET_SIZE(np, len);
return (PyObject *)np;
return list_slice_lock_held(a, ilow, len);
}

PyObject *
Expand Down Expand Up @@ -712,7 +698,7 @@ list_clear_slot(PyObject *self)
* guaranteed the call cannot fail.
*/
static int
list_ass_slice(PyListObject *a, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *v)
list_ass_slice_impl(PyListObject *a, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *v)
{
/* Because [X]DECREF can recursively invoke list operations on
this list, we must postpone all [X]DECREF activity until
Expand All @@ -737,10 +723,10 @@ list_ass_slice(PyListObject *a, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *v)
else {
if (a == b) {
/* Special case "a[i:j] = a" -- copy b first */
v = list_slice(b, 0, Py_SIZE(b));
v = list_slice_lock_held(b, 0, Py_SIZE(b));
if (v == NULL)
return result;
result = list_ass_slice(a, ilow, ihigh, v);
result = list_ass_slice_impl(a, ilow, ihigh, v);
Py_DECREF(v);
return result;
}
Expand Down Expand Up @@ -817,6 +803,23 @@ list_ass_slice(PyListObject *a, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *v)
#undef b
}

static int
list_ass_slice(PyListObject *a, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *v)
{
int ret;
if (v != NULL && PyList_CheckExact(v)) {
Py_BEGIN_CRITICAL_SECTION2(a, v);
ret = list_ass_slice_impl(a, ilow, ihigh, v);
Py_END_CRITICAL_SECTION2();
}
else {
Py_BEGIN_CRITICAL_SECTION(a);
ret = list_ass_slice_impl(a, ilow, ihigh, v);
Py_END_CRITICAL_SECTION();
}
return ret;
}

int
PyList_SetSlice(PyObject *a, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *v)
{
Expand Down Expand Up @@ -2878,8 +2881,7 @@ list_remove_impl(PyListObject *self, PyObject *value)
int cmp = PyObject_RichCompareBool(obj, value, Py_EQ);
Py_DECREF(obj);
if (cmp > 0) {
if (list_ass_slice(self, i, i+1,
(PyObject *)NULL) == 0)
if (list_ass_slice_impl(self, i, i+1, NULL) == 0)
Py_RETURN_NONE;
return NULL;
}
Expand Down

0 comments on commit ed192d7

Please sign in to comment.