diff options
author | Donghee Na <donghee.na@python.org> | 2024-01-26 16:20:21 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-01-26 16:20:21 (GMT) |
commit | f9c505698a1ac27f5a380780767665ffd2fb8ebc (patch) | |
tree | 9bc232cddc90409fe01eb7cf6b38f534a648a2e3 | |
parent | 699779256ec4d4b8afb8211de08ef1382c78c370 (diff) | |
download | cpython-f9c505698a1ac27f5a380780767665ffd2fb8ebc.zip cpython-f9c505698a1ac27f5a380780767665ffd2fb8ebc.tar.gz cpython-f9c505698a1ac27f5a380780767665ffd2fb8ebc.tar.bz2 |
gh-112087: Make list_repr and list_length to be thread-safe (gh-114582)
-rw-r--r-- | Include/cpython/listobject.h | 4 | ||||
-rw-r--r-- | Objects/listobject.c | 27 |
2 files changed, 21 insertions, 10 deletions
diff --git a/Include/cpython/listobject.h b/Include/cpython/listobject.h index 8ade1b1..49f5e8d 100644 --- a/Include/cpython/listobject.h +++ b/Include/cpython/listobject.h @@ -29,7 +29,11 @@ typedef struct { static inline Py_ssize_t PyList_GET_SIZE(PyObject *op) { PyListObject *list = _PyList_CAST(op); +#ifdef Py_GIL_DISABLED + return _Py_atomic_load_ssize_relaxed(&(_PyVarObject_CAST(list)->ob_size)); +#else return Py_SIZE(list); +#endif } #define PyList_GET_SIZE(op) PyList_GET_SIZE(_PyObject_CAST(op)) diff --git a/Objects/listobject.c b/Objects/listobject.c index 1e885f9..56785e5 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -383,18 +383,11 @@ list_dealloc(PyObject *self) } static PyObject * -list_repr(PyObject *self) +list_repr_impl(PyListObject *v) { - PyListObject *v = (PyListObject *)self; - Py_ssize_t i; PyObject *s; _PyUnicodeWriter writer; - - if (Py_SIZE(v) == 0) { - return PyUnicode_FromString("[]"); - } - - i = Py_ReprEnter((PyObject*)v); + Py_ssize_t i = Py_ReprEnter((PyObject*)v); if (i != 0) { return i > 0 ? PyUnicode_FromString("[...]") : NULL; } @@ -439,10 +432,24 @@ error: return NULL; } +static PyObject * +list_repr(PyObject *self) +{ + if (PyList_GET_SIZE(self) == 0) { + return PyUnicode_FromString("[]"); + } + PyListObject *v = (PyListObject *)self; + PyObject *ret = NULL; + Py_BEGIN_CRITICAL_SECTION(v); + ret = list_repr_impl(v); + Py_END_CRITICAL_SECTION(); + return ret; +} + static Py_ssize_t list_length(PyObject *a) { - return Py_SIZE(a); + return PyList_GET_SIZE(a); } static int |