diff --git a/Lib/multiprocessing/resource_tracker.py b/Lib/multiprocessing/resource_tracker.py index 3783c1ffc6e4a92..7d8be0b90053f8d 100644 --- a/Lib/multiprocessing/resource_tracker.py +++ b/Lib/multiprocessing/resource_tracker.py @@ -15,6 +15,7 @@ # this resource tracker process, "killall python" would probably leave unlinked # resources. +import gc import os import signal import sys @@ -80,6 +81,13 @@ def ensure_running(self): This can be run from any process. Usually a child process will use the resource created by its parent.''' + + # gh-109593: Reduce the risk of reentrant calls to ensure_running() by + # running explicitly a garbage collection. Otherwise, finalizers like + # SemLock._cleanup() can make indirectly a reentrant call to + # ensure_running(). + gc.collect() + with self._lock: if self._fd is not None: # resource tracker was launched before, is it still running? diff --git a/Misc/NEWS.d/next/Library/2023-09-20-18-28-12.gh-issue-109593.VVWJDC.rst b/Misc/NEWS.d/next/Library/2023-09-20-18-28-12.gh-issue-109593.VVWJDC.rst new file mode 100644 index 000000000000000..a7ff92ea7446ddc --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-09-20-18-28-12.gh-issue-109593.VVWJDC.rst @@ -0,0 +1,4 @@ +:mod:`multiprocessing`: Reduce the risk of reentrant calls to +``ResourceTracker.ensure_running()`` by running explicitly a garbage +collection, to call pending finalizers, before acquiring the +``ResourceTracker`` lock. Patch by Victor Stinner.