summaryrefslogtreecommitdiffstats
path: root/contrib/tools/python3/Lib/multiprocessing
diff options
context:
space:
mode:
authorshadchin <[email protected]>2025-06-13 00:05:26 +0300
committershadchin <[email protected]>2025-06-13 00:35:30 +0300
commit796b9088366b10b4cd42885101fc20c0b5709b07 (patch)
treef287eacb0b95ffd7cabf95b16cafb4788645dc38 /contrib/tools/python3/Lib/multiprocessing
parentc72bca862651e507d2ff4980ef7f4ff7267a7227 (diff)
Update Python 3 to 3.12.10
commit_hash:dd2398e159fe1d72ea6b12da52fccc933a41a785
Diffstat (limited to 'contrib/tools/python3/Lib/multiprocessing')
-rw-r--r--contrib/tools/python3/Lib/multiprocessing/resource_tracker.py54
1 files changed, 39 insertions, 15 deletions
diff --git a/contrib/tools/python3/Lib/multiprocessing/resource_tracker.py b/contrib/tools/python3/Lib/multiprocessing/resource_tracker.py
index 23fea295c35..e4da1293033 100644
--- a/contrib/tools/python3/Lib/multiprocessing/resource_tracker.py
+++ b/contrib/tools/python3/Lib/multiprocessing/resource_tracker.py
@@ -70,22 +70,46 @@ class ResourceTracker(object):
raise ReentrantCallError(
"Reentrant call into the multiprocessing resource tracker")
- def _stop(self):
- with self._lock:
- # This should not happen (_stop() isn't called by a finalizer)
- # but we check for it anyway.
- if self._lock._recursion_count() > 1:
- return self._reentrant_call_error()
- if self._fd is None:
- # not running
- return
-
- # closing the "alive" file descriptor stops main()
- os.close(self._fd)
- self._fd = None
+ def __del__(self):
+ # making sure child processess are cleaned before ResourceTracker
+ # gets destructed.
+ # see https://github.com/python/cpython/issues/88887
+ self._stop(use_blocking_lock=False)
+
+ def _stop(self, use_blocking_lock=True):
+ if use_blocking_lock:
+ with self._lock:
+ self._stop_locked()
+ else:
+ acquired = self._lock.acquire(blocking=False)
+ try:
+ self._stop_locked()
+ finally:
+ if acquired:
+ self._lock.release()
+
+ def _stop_locked(
+ self,
+ close=os.close,
+ waitpid=os.waitpid,
+ waitstatus_to_exitcode=os.waitstatus_to_exitcode,
+ ):
+ # This shouldn't happen (it might when called by a finalizer)
+ # so we check for it anyway.
+ if self._lock._recursion_count() > 1:
+ return self._reentrant_call_error()
+ if self._fd is None:
+ # not running
+ return
+ if self._pid is None:
+ return
+
+ # closing the "alive" file descriptor stops main()
+ close(self._fd)
+ self._fd = None
- os.waitpid(self._pid, 0)
- self._pid = None
+ waitpid(self._pid, 0)
+ self._pid = None
def getfd(self):
self.ensure_running()