]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.14] gh-148393: Use acquire load for _ma_watcher_tag in dict notify event (gh-14850...
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Mon, 13 Apr 2026 18:38:15 +0000 (20:38 +0200)
committerGitHub <noreply@github.com>
Mon, 13 Apr 2026 18:38:15 +0000 (18:38 +0000)
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.
(cherry picked from commit 19f96f99febe9eadbcc58ffc042791fb017ac90b)

Co-authored-by: Sam Gross <colesbury@gmail.com>
Include/internal/pycore_dict.h
Include/internal/pycore_pyatomic_ft_wrappers.h

index 346e4e64a42a56e370dafac3fd0c09d66206872b..77d99891b306819a4f267bf89107fea201a6c15d 100644 (file)
@@ -286,7 +286,7 @@ _PyDict_NotifyEvent(PyInterpreterState *interp,
                     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 3019fada11ee4f032e2c3b824208d284f2ec8b31..31628528321e1b09f9e96779886e54f8c318d24c 100644 (file)
@@ -47,6 +47,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) \
@@ -147,6 +149,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