Skip to content

Commit

Permalink
gh-128717: Stop-the-world when setting the recursion limit (#128741)
Browse files Browse the repository at this point in the history
  • Loading branch information
ZeroIntensity authored Jan 12, 2025
1 parent ff39e3f commit f6c61bf
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 0 deletions.
15 changes: 15 additions & 0 deletions Lib/test/test_free_threading/test_races.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Original file line number Diff line number Diff line change
@@ -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.
2 changes: 2 additions & 0 deletions Python/ceval.c
Original file line number Diff line number Diff line change
Expand Up @@ -294,13 +294,15 @@ 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;
p->py_recursion_limit = 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()
Expand Down

0 comments on commit f6c61bf

Please sign in to comment.