]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-151228: fix data race on clearing embedded dict values (#151330)
authorKumar Aditya <kumaraditya@python.org>
Thu, 11 Jun 2026 16:07:00 +0000 (21:37 +0530)
committerGitHub <noreply@github.com>
Thu, 11 Jun 2026 16:07:00 +0000 (21:37 +0530)
Lib/test/test_free_threading/test_dict.py
Objects/dictobject.c

index dfe0634211d4b02fedcaf09ab4a9982dcd9b1f6d..ad23290a92ab3458f760741540e7daf102f7285c 100644 (file)
@@ -296,6 +296,24 @@ class TestDict(TestCase):
 
         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
index e279c8765dd464aa77983c796ddc3a3b64cb4261..25dc81f726f59cb02f59cbcde2caba22e33527a6 100644 (file)
@@ -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++) {