From ed192d74934df963a0a15c81328371881b19b953 Mon Sep 17 00:00:00 2001 From: Donghee Na Date: Fri, 23 Feb 2024 23:13:34 +0900 Subject: [PATCH] Make list_ass_slice to be thread-safe(?) --- Objects/listobject.c | 48 +++++++++++++++++++++++--------------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/Objects/listobject.c b/Objects/listobject.c index 6cfb4d358ba175..2d29f4cfb9712a 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -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]; @@ -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 * @@ -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 @@ -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; } @@ -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) { @@ -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; }