https://github.com/python/cpython/commit/1051384fcdfa88dd88d66dfc93b60aec9ca1ad2e
commit: 1051384fcdfa88dd88d66dfc93b60aec9ca1ad2e
branch: main
author: sobolevn <[email protected]>
committer: sobolevn <[email protected]>
date: 2026-07-08T09:41:38Z
summary:

gh-153292: Fix data race in `threading.RLock.__repr__` in FT builds (#153299)

files:
A Lib/test/test_free_threading/test_threading.py
A Misc/NEWS.d/next/Library/2026-07-08-01-03-17.gh-issue-153292.oHDt3l.rst
M Modules/_threadmodule.c

diff --git a/Lib/test/test_free_threading/test_threading.py 
b/Lib/test/test_free_threading/test_threading.py
new file mode 100644
index 000000000000000..b5a5ca272b9405a
--- /dev/null
+++ b/Lib/test/test_free_threading/test_threading.py
@@ -0,0 +1,26 @@
+import unittest
+from test.support import threading_helper
+
+threading_helper.requires_working_threading(module=True)
+
+
+class TestRlock(unittest.TestCase):
+    def test_repr_race(self):
+        # gh-153292
+        import _thread
+        r = _thread.RLock()
+
+        def repr_thread():
+            for _ in range(2000):
+                repr(r)
+
+        def mutate_thread():
+            for _ in range(2000):
+                r.acquire()
+                r.release()
+
+        threading_helper.run_concurrently([repr_thread, mutate_thread])
+
+
+if __name__ == "__main__":
+    unittest.main()
diff --git 
a/Misc/NEWS.d/next/Library/2026-07-08-01-03-17.gh-issue-153292.oHDt3l.rst 
b/Misc/NEWS.d/next/Library/2026-07-08-01-03-17.gh-issue-153292.oHDt3l.rst
new file mode 100644
index 000000000000000..dc363e160074302
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2026-07-08-01-03-17.gh-issue-153292.oHDt3l.rst
@@ -0,0 +1 @@
+Fix data race in repr of :class:`threading.RLock` in free-threading build.
diff --git a/Modules/_threadmodule.c b/Modules/_threadmodule.c
index 7e1884edf5213e3..e999fe20287e2d6 100644
--- a/Modules/_threadmodule.c
+++ b/Modules/_threadmodule.c
@@ -1288,7 +1288,7 @@ static PyObject *
 rlock_repr(PyObject *op)
 {
     rlockobject *self = rlockobject_CAST(op);
-    PyThread_ident_t owner = self->lock.thread;
+    PyThread_ident_t owner = FT_ATOMIC_LOAD_ULLONG_RELAXED(self->lock.thread);
     int locked = rlock_locked_impl(self);
     size_t count;
     if (locked) {

_______________________________________________
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