--- /dev/null
+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()
--- /dev/null
+Fix data race in repr of :class:`threading.RLock` in free-threading build.
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) {