]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-128717: Stop-the-world when setting the recursion limit (#128741)
authorPeter Bierma <zintensitydev@gmail.com>
Sun, 12 Jan 2025 13:04:30 +0000 (08:04 -0500)
committerGitHub <noreply@github.com>
Sun, 12 Jan 2025 13:04:30 +0000 (18:34 +0530)
Lib/test/test_free_threading/test_races.py
Misc/NEWS.d/next/Core_and_Builtins/2025-01-11-12-39-17.gh-issue-128717.i65d06.rst [new file with mode: 0644]
Python/ceval.c

index 69982558a067a52a28a427c866788ecbe7b74e6b..85aa69c8cd494f1eec785882a141e6146d7a25dc 100644 (file)
@@ -270,6 +270,21 @@ class TestRaces(TestBase):
 
         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 (file)
index 0000000..212c6d3
--- /dev/null
@@ -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.
index e92a11b16cec810e31072c365d04a6bdb3f0dfaa..e0362c3c89fe6a3a2c95646c5ba071b1a4ed09a2 100644 (file)
@@ -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()