File tree 3 files changed +36
-0
lines changed
Misc/NEWS.d/next/Core_and_Builtins 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):
362
362
finally :
363
363
sys .setrecursionlimit (old_limit )
364
364
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
+
365
395
def test_getwindowsversion (self ):
366
396
# Raise SkipTest if sys doesn't have getwindowsversion attribute
367
397
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
265
265
Py_SetRecursionLimit (int new_limit )
266
266
{
267
267
PyInterpreterState * interp = _PyInterpreterState_GET ();
268
+ _PyEval_StopTheWorld (interp );
269
+ HEAD_LOCK (interp -> runtime );
268
270
interp -> ceval .recursion_limit = new_limit ;
269
271
for (PyThreadState * p = interp -> threads .head ; p != NULL ; p = p -> next ) {
270
272
int depth = p -> py_recursion_limit - p -> py_recursion_remaining ;
271
273
p -> py_recursion_limit = new_limit ;
272
274
p -> py_recursion_remaining = new_limit - depth ;
273
275
}
276
+ HEAD_UNLOCK (interp -> runtime );
277
+ _PyEval_StartTheWorld (interp );
274
278
}
275
279
276
280
/* The function _Py_EnterRecursiveCallTstate() only calls _Py_CheckRecursiveCall()
You can’t perform that action at this time.
0 commit comments