From 87d7a19ef0a751925be1f703858831c5e0c4fb57 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Wed, 21 May 2025 11:36:39 +0200 Subject: [PATCH] [3.14] gh-133980: use atomic store in `PyObject_GenericSetDict` (GH-133988) (#134354) gh-133980: use atomic store in `PyObject_GenericSetDict` (GH-133988) (cherry picked from commit ec39fd2c20323ee9814a1137b1a0819e92efae4e) Co-authored-by: Kumar Aditya --- Lib/test/test_free_threading/test_dict.py | 16 ++++++++++++++++ Objects/object.c | 8 +++++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_free_threading/test_dict.py b/Lib/test/test_free_threading/test_dict.py index 476cc3178d8..5d5d4e226ca 100644 --- a/Lib/test/test_free_threading/test_dict.py +++ b/Lib/test/test_free_threading/test_dict.py @@ -228,6 +228,22 @@ class TestDict(TestCase): self.assertEqual(count, 0) + def test_racing_object_get_set_dict(self): + e = Exception() + + def writer(): + for i in range(10000): + e.__dict__ = {1:2} + + def reader(): + for i in range(10000): + e.__dict__ + + t1 = Thread(target=writer) + t2 = Thread(target=reader) + + with threading_helper.start_threads([t1, t2]): + pass if __name__ == "__main__": unittest.main() diff --git a/Objects/object.c b/Objects/object.c index 723b0427e69..af1aa217f75 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -1931,7 +1931,13 @@ PyObject_GenericSetDict(PyObject *obj, PyObject *value, void *context) return -1; } Py_BEGIN_CRITICAL_SECTION(obj); - Py_XSETREF(*dictptr, Py_NewRef(value)); + PyObject *olddict = *dictptr; + FT_ATOMIC_STORE_PTR_RELEASE(*dictptr, Py_NewRef(value)); +#ifdef Py_GIL_DISABLED + _PyObject_XDecRefDelayed(olddict); +#else + Py_XDECREF(olddict); +#endif Py_END_CRITICAL_SECTION(); return 0; }