@@ -1957,3 +1957,165 @@ diff Python-3.12.8/Lib/test/_test_multiprocessing.py Python-3.12.9/Lib/test/_tes
1957
1957
> # restore sigmask to what it was before executing test
1958
1958
> signal.pthread_sigmask(signal.SIG_SETMASK, orig_sigmask)
1959
1959
>
1960
+ # ----------------------------------------------------------------------
1961
+ diff Python-3.12.9/Lib/multiprocessing/resource_tracker.py Python-3.12.10/Lib/multiprocessing/resource_tracker.py
1962
+ 73,85c73,109
1963
+ < def _stop(self):
1964
+ < with self._lock:
1965
+ < # This should not happen (_stop() isn't called by a finalizer)
1966
+ < # but we check for it anyway.
1967
+ < if self._lock._recursion_count() > 1:
1968
+ < return self._reentrant_call_error()
1969
+ < if self._fd is None:
1970
+ < # not running
1971
+ < return
1972
+ <
1973
+ < # closing the "alive" file descriptor stops main()
1974
+ < os.close(self._fd)
1975
+ < self._fd = None
1976
+ ---
1977
+ > def __del__(self):
1978
+ > # making sure child processess are cleaned before ResourceTracker
1979
+ > # gets destructed.
1980
+ > # see https://github.com/python/cpython/issues/88887
1981
+ > self._stop(use_blocking_lock=False)
1982
+ >
1983
+ > def _stop(self, use_blocking_lock=True):
1984
+ > if use_blocking_lock:
1985
+ > with self._lock:
1986
+ > self._stop_locked()
1987
+ > else:
1988
+ > acquired = self._lock.acquire(blocking=False)
1989
+ > try:
1990
+ > self._stop_locked()
1991
+ > finally:
1992
+ > if acquired:
1993
+ > self._lock.release()
1994
+ >
1995
+ > def _stop_locked(
1996
+ > self,
1997
+ > close=os.close,
1998
+ > waitpid=os.waitpid,
1999
+ > waitstatus_to_exitcode=os.waitstatus_to_exitcode,
2000
+ > ):
2001
+ > # This shouldn't happen (it might when called by a finalizer)
2002
+ > # so we check for it anyway.
2003
+ > if self._lock._recursion_count() > 1:
2004
+ > return self._reentrant_call_error()
2005
+ > if self._fd is None:
2006
+ > # not running
2007
+ > return
2008
+ > if self._pid is None:
2009
+ > return
2010
+ >
2011
+ > # closing the "alive" file descriptor stops main()
2012
+ > close(self._fd)
2013
+ > self._fd = None
2014
+ 87,88c111,112
2015
+ < os.waitpid(self._pid, 0)
2016
+ < self._pid = None
2017
+ ---
2018
+ > waitpid(self._pid, 0)
2019
+ > self._pid = None
2020
+ diff Python-3.12.9/Lib/test/_test_multiprocessing.py Python-3.12.10/Lib/test/_test_multiprocessing.py
2021
+ 591c591,592
2022
+ < p = self.Process(target=time.sleep, args=(DELTA,))
2023
+ ---
2024
+ > event = self.Event()
2025
+ > p = self.Process(target=event.wait, args=())
2026
+ 594,596c595,600
2027
+ < p.daemon = True
2028
+ < p.start()
2029
+ < self.assertIn(p, self.active_children())
2030
+ ---
2031
+ > try:
2032
+ > p.daemon = True
2033
+ > p.start()
2034
+ > self.assertIn(p, self.active_children())
2035
+ > finally:
2036
+ > event.set()
2037
+ 1580c1584
2038
+ < for i in range(10):
2039
+ ---
2040
+ > for _ in support.sleeping_retry(support.SHORT_TIMEOUT):
2041
+ 1586,1587c1590
2042
+ < time.sleep(DELTA)
2043
+ < time.sleep(DELTA)
2044
+ ---
2045
+ >
2046
+ 1609d1611
2047
+ < self.addCleanup(p.join)
2048
+ 1611,1614c1613,1615
2049
+ < p = threading.Thread(target=self.f, args=(cond, sleeping, woken))
2050
+ < p.daemon = True
2051
+ < p.start()
2052
+ < self.addCleanup(p.join)
2053
+ ---
2054
+ > t = threading.Thread(target=self.f, args=(cond, sleeping, woken))
2055
+ > t.daemon = True
2056
+ > t.start()
2057
+ 1621,1622c1622
2058
+ < time.sleep(DELTA)
2059
+ < self.assertReturnsIfImplemented(0, get_value, woken)
2060
+ ---
2061
+ > self.assertReachesEventually(lambda: get_value(woken), 0)
2062
+ 1630,1631c1630
2063
+ < time.sleep(DELTA)
2064
+ < self.assertReturnsIfImplemented(1, get_value, woken)
2065
+ ---
2066
+ > self.assertReachesEventually(lambda: get_value(woken), 1)
2067
+ 1639,1640c1638
2068
+ < time.sleep(DELTA)
2069
+ < self.assertReturnsIfImplemented(2, get_value, woken)
2070
+ ---
2071
+ > self.assertReachesEventually(lambda: get_value(woken), 2)
2072
+ 1644c1642,1644
2073
+ < p.join()
2074
+ ---
2075
+ >
2076
+ > threading_helper.join_thread(t)
2077
+ > join_process(p)
2078
+ 1651a1652
2079
+ > workers = []
2080
+ 1657c1658
2081
+ < self.addCleanup(p.join)
2082
+ ---
2083
+ > workers.append(p)
2084
+ 1663c1664
2085
+ < self.addCleanup(t.join)
2086
+ ---
2087
+ > workers.append(t)
2088
+ 1682c1683
2089
+ < self.addCleanup(p.join)
2090
+ ---
2091
+ > workers.append(p)
2092
+ 1687c1688
2093
+ < self.addCleanup(t.join)
2094
+ ---
2095
+ > workers.append(t)
2096
+ 1703c1704,1706
2097
+ < self.assertReachesEventually(lambda: get_value(woken), 6)
2098
+ ---
2099
+ > for i in range(6):
2100
+ > woken.acquire()
2101
+ > self.assertReturnsIfImplemented(0, get_value, woken)
2102
+ 1707a1711,1714
2103
+ > for w in workers:
2104
+ > # NOTE: join_process and join_thread are the same
2105
+ > threading_helper.join_thread(w)
2106
+ >
2107
+ 1713a1721
2108
+ > workers = []
2109
+ 1718c1726
2110
+ < self.addCleanup(p.join)
2111
+ ---
2112
+ > workers.append(p)
2113
+ 1723c1731
2114
+ < self.addCleanup(t.join)
2115
+ ---
2116
+ > workers.append(t)
2117
+ 1757a1766,1769
2118
+ > for w in workers:
2119
+ > # NOTE: join_process and join_thread are the same
2120
+ > threading_helper.join_thread(w)
2121
+ >
0 commit comments