https://github.com/python/cpython/commit/44fca7ed29a552c21bceab9363af1c8f8e6c3084
commit: 44fca7ed29a552c21bceab9363af1c8f8e6c3084
branch: 3.15
author: Miss Islington (bot) <[email protected]>
committer: encukou <[email protected]>
date: 2026-07-27T18:02:16+02:00
summary:

[3.15] gh-154431: Revert "gh-154431: Fix data race in `sys.audithook` 
(GH-154462)" (GH-154769) (GH-154774)

This reverts commit 596cd5c5d7b6ada3e50c6499447eb90a065769ad.
This commit caused a refleak.

(cherry picked from commit c7b9a13a7528342fdac47a2121248f0b989131e5)

Co-authored-by: Petr Viktorin <[email protected]>

files:
D Misc/NEWS.d/next/Library/2026-07-22-12-42-53.gh-issue-154431.U2kXXZ.rst
M Include/internal/pycore_interp_structs.h
M Lib/test/test_free_threading/test_sys.py
M Python/pystate.c
M Python/sysmodule.c

diff --git a/Include/internal/pycore_interp_structs.h 
b/Include/internal/pycore_interp_structs.h
index c1bf1770266681b..d8e83cf2ff5c9a9 100644
--- a/Include/internal/pycore_interp_structs.h
+++ b/Include/internal/pycore_interp_structs.h
@@ -988,7 +988,6 @@ struct _is {
     struct _obmalloc_state *obmalloc;
 
     PyObject *audit_hooks;
-    PyMutex audit_hooks_mutex;
     PyType_WatchCallback type_watchers[TYPE_MAX_WATCHERS];
     PyCode_WatchCallback code_watchers[CODE_MAX_WATCHERS];
     PyContext_WatchCallback context_watchers[CONTEXT_MAX_WATCHERS];
diff --git a/Lib/test/test_free_threading/test_sys.py 
b/Lib/test/test_free_threading/test_sys.py
index b8ba933cb01adc0..271fdd13c62b668 100644
--- a/Lib/test/test_free_threading/test_sys.py
+++ b/Lib/test/test_free_threading/test_sys.py
@@ -44,20 +44,6 @@ def worker(worker_id):
         workers = [lambda: worker(i) for i in range(5)]
         threading_helper.run_concurrently(workers)
 
-    def test_sys_audit_hooks(self):
-        def _hook(*args):
-            return None
-
-        def adder():
-            for _ in range(100):
-                sys.addaudithook(_hook)
-
-        def auditor():
-            for _ in range(2000):
-                sys.audit("fusil.tsan.test")
-
-        threading_helper.run_concurrently([adder, auditor])
-
 
 if __name__ == "__main__":
     unittest.main()
diff --git 
a/Misc/NEWS.d/next/Library/2026-07-22-12-42-53.gh-issue-154431.U2kXXZ.rst 
b/Misc/NEWS.d/next/Library/2026-07-22-12-42-53.gh-issue-154431.U2kXXZ.rst
deleted file mode 100644
index a56c3b3a6f21f3a..000000000000000
--- a/Misc/NEWS.d/next/Library/2026-07-22-12-42-53.gh-issue-154431.U2kXXZ.rst
+++ /dev/null
@@ -1 +0,0 @@
-Fixes a data race in free-threading build in :func:`sys.addaudithook`.
diff --git a/Python/pystate.c b/Python/pystate.c
index 185957f6343ba6a..8349df1b573952d 100644
--- a/Python/pystate.c
+++ b/Python/pystate.c
@@ -580,7 +580,6 @@ init_interpreter(PyInterpreterState *interp,
     llist_init(&interp->mem_free_queue.head);
     llist_init(&interp->asyncio_tasks_head);
     interp->asyncio_tasks_lock = (PyMutex){0};
-    interp->audit_hooks_mutex = (PyMutex){0};
     for (int i = 0; i < _PY_MONITORING_UNGROUPED_EVENTS; i++) {
         interp->monitors.tools[i] = 0;
     }
diff --git a/Python/sysmodule.c b/Python/sysmodule.c
index 5140ad86d499236..aa9ff9e9a455de7 100644
--- a/Python/sysmodule.c
+++ b/Python/sysmodule.c
@@ -236,7 +236,7 @@ should_audit(PyInterpreterState *interp)
         return 0;
     }
     return (interp->runtime->audit_hooks.head
-            || FT_ATOMIC_LOAD_PTR_ACQUIRE(interp->audit_hooks)
+            || interp->audit_hooks
             || PyDTrace_AUDIT_ENABLED());
 }
 
@@ -306,14 +306,13 @@ sys_audit_tstate(PyThreadState *ts, const char *event,
     }
 
     /* Call interpreter hooks */
-    PyObject *audit_hooks = FT_ATOMIC_LOAD_PTR_ACQUIRE(is->audit_hooks);
-    if (audit_hooks) {
+    if (is->audit_hooks) {
         eventName = PyUnicode_FromString(event);
         if (!eventName) {
             goto exit;
         }
 
-        hooks = PyObject_GetIter(audit_hooks);
+        hooks = PyObject_GetIter(is->audit_hooks);
         if (!hooks) {
             goto exit;
         }
@@ -537,29 +536,20 @@ sys_addaudithook_impl(PyObject *module, PyObject *hook)
     }
 
     PyInterpreterState *interp = tstate->interp;
-    PyMutex mutex = interp->audit_hooks_mutex;
-    PyMutex_Lock(&mutex);
-
     if (interp->audit_hooks == NULL) {
-        PyObject *new_list = PyList_New(0);
-        if (new_list == NULL) {
-            goto error;
+        interp->audit_hooks = PyList_New(0);
+        if (interp->audit_hooks == NULL) {
+            return NULL;
         }
         /* Avoid having our list of hooks show up in the GC module */
-        PyObject_GC_UnTrack(new_list);
-        FT_ATOMIC_STORE_PTR_RELEASE(interp->audit_hooks, new_list);
+        PyObject_GC_UnTrack(interp->audit_hooks);
     }
 
     if (PyList_Append(interp->audit_hooks, hook) < 0) {
-        goto error;
+        return NULL;
     }
 
-    PyMutex_Unlock(&mutex);
     Py_RETURN_NONE;
-
-error:
-    PyMutex_Unlock(&mutex);
-    return NULL;
 }
 
 /*[clinic input]

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]

Reply via email to