From 08d4e752b478ece6184f1865120c0c949705422e Mon Sep 17 00:00:00 2001 From: Kumar Aditya Date: Tue, 18 Feb 2025 14:16:50 +0000 Subject: [PATCH] use relaxed atomics for it_index --- Lib/test/test_free_threading/test_list.py | 18 ++++++++++++++++++ Objects/listobject.c | 8 ++++---- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/Lib/test/test_free_threading/test_list.py b/Lib/test/test_free_threading/test_list.py index a705161369e8dd..2f30999a348979 100644 --- a/Lib/test/test_free_threading/test_list.py +++ b/Lib/test/test_free_threading/test_list.py @@ -71,6 +71,24 @@ def reader_func(): for reader in readers: reader.join() + def test_list_iterator_reduce(self): + l = list(range(100)) + + for it in [iter(l), iter(reversed(l))]: + + def reduce(): + for i in range(100): + it.__reduce__() + + def setstate(): + for i in range(100): + it.__setstate__(i) + + t1 = Thread(target=reduce) + t2 = Thread(target=setstate) + + with threading_helper.start_threads([t1, t2]): + pass if __name__ == "__main__": unittest.main() diff --git a/Objects/listobject.c b/Objects/listobject.c index 120e353b709e7b..ccc07378e6c0be 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -3988,12 +3988,12 @@ listiter_setstate(PyObject *self, PyObject *state) Py_ssize_t index = PyLong_AsSsize_t(state); if (index == -1 && PyErr_Occurred()) return NULL; - if (it->it_seq != NULL) { + if (FT_ATOMIC_LOAD_SSIZE_RELAXED(it->it_index) >= 0) { if (index < -1) index = -1; else if (index > PyList_GET_SIZE(it->it_seq)) index = PyList_GET_SIZE(it->it_seq); /* iterator exhausted */ - it->it_index = index; + FT_ATOMIC_STORE_SSIZE_RELAXED(it->it_index, index); } Py_RETURN_NONE; } @@ -4140,12 +4140,12 @@ listreviter_setstate(PyObject *self, PyObject *state) Py_ssize_t index = PyLong_AsSsize_t(state); if (index == -1 && PyErr_Occurred()) return NULL; - if (it->it_seq != NULL) { + if (FT_ATOMIC_LOAD_SSIZE_RELAXED(it->it_index) >= 0) { if (index < -1) index = -1; else if (index > PyList_GET_SIZE(it->it_seq) - 1) index = PyList_GET_SIZE(it->it_seq) - 1; - it->it_index = index; + FT_ATOMIC_STORE_SSIZE_RELAXED(it->it_index, index); } Py_RETURN_NONE; }