From 97eda71275a3433cff634b24fbe1af91703ac671 Mon Sep 17 00:00:00 2001 From: Kumar Aditya Date: Thu, 11 Jun 2026 17:07:17 +0530 Subject: [PATCH] fix data race on clearing embedded values --- Lib/test/test_free_threading/test_dict.py | 18 ++++++++++++++++++ Objects/dictobject.c | 2 +- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_free_threading/test_dict.py b/Lib/test/test_free_threading/test_dict.py index dfe0634211d4b02..ad23290a92ab345 100644 --- a/Lib/test/test_free_threading/test_dict.py +++ b/Lib/test/test_free_threading/test_dict.py @@ -296,6 +296,24 @@ def reader(): threading_helper.run_concurrently([clearer, reader, reader]) + def test_racing_embedded_values_clear_and_lookup(self): + class C: + pass + + obj = C() + def writer(): + for _ in range(1000): + obj.x = 1 + obj.y = 2 + obj.z = 3 + obj.__dict__.clear() + + def reader(): + for _ in range(1000): + obj.__dict__.get('x') + + threading_helper.run_concurrently([writer, reader, reader]) + def test_racing_dict_update_and_method_lookup(self): # gh-144295: test race between dict modifications and method lookups. # Uses BytesIO because the race requires a type without Py_TPFLAGS_INLINE_VALUES diff --git a/Objects/dictobject.c b/Objects/dictobject.c index e279c8765dd464a..25dc81f726f59cb 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -3039,7 +3039,7 @@ clear_embedded_values(PyDictValues *values, Py_ssize_t nentries) assert(nentries <= SHARED_KEYS_MAX_SIZE); for (Py_ssize_t i = 0; i < nentries; i++) { refs[i] = values->values[i]; - values->values[i] = NULL; + FT_ATOMIC_STORE_PTR_RELEASE(values->values[i], NULL); } values->size = 0; for (Py_ssize_t i = 0; i < nentries; i++) {