File tree Expand file tree Collapse file tree 3 files changed +36
-0
lines changed
Misc/NEWS.d/next/Core_and_Builtins Expand file tree Collapse file tree 3 files changed +36
-0
lines changed Original file line number Diff line number Diff line change @@ -362,6 +362,36 @@ def test_setrecursionlimit_to_depth(self):
362362 finally :
363363 sys .setrecursionlimit (old_limit )
364364
365+ @unittest .skipUnless (support .Py_GIL_DISABLED , "only meaningful if the GIL is disabled" )
366+ @threading_helper .requires_working_threading ()
367+ def test_racing_recursion_limit (self ):
368+ from threading import Thread
369+ def something_recursive ():
370+ def count (n ):
371+ if n > 0 :
372+ return count (n - 1 ) + 1
373+ return 0
374+
375+ count (50 )
376+
377+ def set_recursion_limit ():
378+ for limit in range (100 , 200 ):
379+ sys .setrecursionlimit (limit )
380+
381+ threads = []
382+ for _ in range (5 ):
383+ threads .append (Thread (target = set_recursion_limit ))
384+
385+ for _ in range (5 ):
386+ threads .append (Thread (target = something_recursive ))
387+
388+ with threading_helper .catch_threading_exception () as cm :
389+ with threading_helper .start_threads (threads ):
390+ pass
391+
392+ if cm .exc_value :
393+ raise cm .exc_value
394+
365395 def test_getwindowsversion (self ):
366396 # Raise SkipTest if sys doesn't have getwindowsversion attribute
367397 test .support .get_attribute (sys , "getwindowsversion" )
Original file line number Diff line number Diff line change 1+ Fix a crash when setting the recursion limit while other threads are active
2+ on the :term: `free threaded <free threading> ` build.
Original file line number Diff line number Diff line change @@ -265,12 +265,16 @@ void
265265Py_SetRecursionLimit (int new_limit )
266266{
267267 PyInterpreterState * interp = _PyInterpreterState_GET ();
268+ _PyEval_StopTheWorld (interp );
269+ HEAD_LOCK (interp -> runtime );
268270 interp -> ceval .recursion_limit = new_limit ;
269271 for (PyThreadState * p = interp -> threads .head ; p != NULL ; p = p -> next ) {
270272 int depth = p -> py_recursion_limit - p -> py_recursion_remaining ;
271273 p -> py_recursion_limit = new_limit ;
272274 p -> py_recursion_remaining = new_limit - depth ;
273275 }
276+ HEAD_UNLOCK (interp -> runtime );
277+ _PyEval_StartTheWorld (interp );
274278}
275279
276280/* The function _Py_EnterRecursiveCallTstate() only calls _Py_CheckRecursiveCall()
You can’t perform that action at this time.
0 commit comments