]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-148393: Use acquire load for _ma_watcher_tag in dict notify event (gh-148509)
authorSam Gross <colesbury@gmail.com>
Mon, 13 Apr 2026 18:11:28 +0000 (14:11 -0400)
committerGitHub <noreply@github.com>
Mon, 13 Apr 2026 18:11:28 +0000 (14:11 -0400)
The watcher-bits read in _PyDict_NotifyEvent needs to use acquire to
synchronize with the release from PyDict_Watch so that the callback
publication is visible before the callback is invoked.

Include/internal/pycore_dict.h
Include/internal/pycore_pyatomic_ft_wrappers.h

index 5bbea187394db6cc9e2508ed02d62a6927b12489..68d353b213c097726bd4eea2c4ddb6191a8132e0 100644 (file)
@@ -292,7 +292,7 @@ _PyDict_NotifyEvent(PyDict_WatchEvent event,
                     PyObject *value)
 {
     assert(Py_REFCNT((PyObject*)mp) > 0);
-    int watcher_bits = FT_ATOMIC_LOAD_UINT64_RELAXED(mp->_ma_watcher_tag) & DICT_WATCHER_MASK;
+    int watcher_bits = FT_ATOMIC_LOAD_UINT64_ACQUIRE(mp->_ma_watcher_tag) & DICT_WATCHER_MASK;
     if (watcher_bits) {
         RARE_EVENT_STAT_INC(watched_dict_modification);
         _PyDict_SendEvent(watcher_bits, event, mp, key, value);
index 3155481bb5c36b9b4f9388e07ffaf7d219974bfc..fafdd728a8229a94b75f8557622660a0c40b0f49 100644 (file)
@@ -49,6 +49,8 @@ extern "C" {
     _Py_atomic_load_uint16_relaxed(&value)
 #define FT_ATOMIC_LOAD_UINT32_RELAXED(value) \
     _Py_atomic_load_uint32_relaxed(&value)
+#define FT_ATOMIC_LOAD_UINT64_ACQUIRE(value) \
+    _Py_atomic_load_uint64_acquire(&value)
 #define FT_ATOMIC_LOAD_UINT64_RELAXED(value) \
     _Py_atomic_load_uint64_relaxed(&value)
 #define FT_ATOMIC_LOAD_ULONG_RELAXED(value) \
@@ -154,6 +156,7 @@ extern "C" {
 #define FT_ATOMIC_LOAD_UINT8_RELAXED(value) value
 #define FT_ATOMIC_LOAD_UINT16_RELAXED(value) value
 #define FT_ATOMIC_LOAD_UINT32_RELAXED(value) value
+#define FT_ATOMIC_LOAD_UINT64_ACQUIRE(value) value
 #define FT_ATOMIC_LOAD_UINT64_RELAXED(value) value
 #define FT_ATOMIC_LOAD_ULONG_RELAXED(value) value
 #define FT_ATOMIC_STORE_PTR_RELAXED(value, new_value) value = new_value