https://github.com/python/cpython/commit/f6c61bf2d7d8b66ccd9f16e723546bdcc251a3d0
commit: f6c61bf2d7d8b66ccd9f16e723546bdcc251a3d0
branch: main
author: Peter Bierma <[email protected]>
committer: kumaraditya303 <[email protected]>
date: 2025-01-12T18:34:30+05:30
summary:

gh-128717: Stop-the-world when setting the recursion limit (#128741)

files:
A 
Misc/NEWS.d/next/Core_and_Builtins/2025-01-11-12-39-17.gh-issue-128717.i65d06.rst
M Lib/test/test_free_threading/test_races.py
M Python/ceval.c

diff --git a/Lib/test/test_free_threading/test_races.py 
b/Lib/test/test_free_threading/test_races.py
index 69982558a067a5..85aa69c8cd494f 100644
--- a/Lib/test/test_free_threading/test_races.py
+++ b/Lib/test/test_free_threading/test_races.py
@@ -270,6 +270,21 @@ def mutate():
 
         do_race(set_value, mutate)
 
+    def test_racing_recursion_limit(self):
+        def something_recursive():
+            def count(n):
+                if n > 0:
+                    return count(n - 1) + 1
+                return 0
+
+            count(50)
+
+        def set_recursion_limit():
+            for limit in range(100, 200):
+                sys.setrecursionlimit(limit)
+
+        do_race(something_recursive, set_recursion_limit)
+
 
 if __name__ == "__main__":
     unittest.main()
diff --git 
a/Misc/NEWS.d/next/Core_and_Builtins/2025-01-11-12-39-17.gh-issue-128717.i65d06.rst
 
b/Misc/NEWS.d/next/Core_and_Builtins/2025-01-11-12-39-17.gh-issue-128717.i65d06.rst
new file mode 100644
index 00000000000000..212c6d3cb97216
--- /dev/null
+++ 
b/Misc/NEWS.d/next/Core_and_Builtins/2025-01-11-12-39-17.gh-issue-128717.i65d06.rst
@@ -0,0 +1,2 @@
+Fix a crash when setting the recursion limit while other threads are active
+on the :term:`free threaded <free threading>` build.
diff --git a/Python/ceval.c b/Python/ceval.c
index e92a11b16cec81..e0362c3c89fe6a 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -294,6 +294,7 @@ void
 Py_SetRecursionLimit(int new_limit)
 {
     PyInterpreterState *interp = _PyInterpreterState_GET();
+    _PyEval_StopTheWorld(interp);
     interp->ceval.recursion_limit = new_limit;
     _Py_FOR_EACH_TSTATE_BEGIN(interp, p) {
         int depth = p->py_recursion_limit - p->py_recursion_remaining;
@@ -301,6 +302,7 @@ Py_SetRecursionLimit(int new_limit)
         p->py_recursion_remaining = new_limit - depth;
     }
     _Py_FOR_EACH_TSTATE_END(interp);
+    _PyEval_StartTheWorld(interp);
 }
 
 /* The function _Py_EnterRecursiveCallTstate() only calls 
_Py_CheckRecursiveCall()

_______________________________________________
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