@@ -75,29 +75,53 @@ def _reentrant_call_error(self):
7575 raise ReentrantCallError (
7676 "Reentrant call into the multiprocessing resource tracker" )
7777
78- def _stop (self ):
79- with self ._lock :
80- # This should not happen (_stop() isn't called by a finalizer)
81- # but we check for it anyway.
82- if self ._lock ._recursion_count () > 1 :
83- return self ._reentrant_call_error ()
84- if self ._fd is None :
85- # not running
86- return
87-
88- # closing the "alive" file descriptor stops main()
89- os .close (self ._fd )
90- self ._fd = None
78+ def __del__ (self ):
79+ # making sure child processess are cleaned before ResourceTracker
80+ # gets destructed.
81+ # see https://github.com/python/cpython/issues/88887
82+ self ._stop (use_blocking_lock = False )
83+
84+ def _stop (self , use_blocking_lock = True ):
85+ if use_blocking_lock :
86+ with self ._lock :
87+ self ._stop_locked ()
88+ else :
89+ acquired = self ._lock .acquire (blocking = False )
90+ try :
91+ self ._stop_locked ()
92+ finally :
93+ if acquired :
94+ self ._lock .release ()
95+
96+ def _stop_locked (
97+ self ,
98+ close = os .close ,
99+ waitpid = os .waitpid ,
100+ waitstatus_to_exitcode = os .waitstatus_to_exitcode ,
101+ ):
102+ # This shouldn't happen (it might when called by a finalizer)
103+ # so we check for it anyway.
104+ if self ._lock ._recursion_count () > 1 :
105+ return self ._reentrant_call_error ()
106+ if self ._fd is None :
107+ # not running
108+ return
109+ if self ._pid is None :
110+ return
111+
112+ # closing the "alive" file descriptor stops main()
113+ close (self ._fd )
114+ self ._fd = None
91115
92- _ , status = os . waitpid (self ._pid , 0 )
116+ _ , status = waitpid (self ._pid , 0 )
93117
94- self ._pid = None
118+ self ._pid = None
95119
96- try :
97- self ._exitcode = os . waitstatus_to_exitcode (status )
98- except ValueError :
99- # os.waitstatus_to_exitcode may raise an exception for invalid values
100- self ._exitcode = None
120+ try :
121+ self ._exitcode = waitstatus_to_exitcode (status )
122+ except ValueError :
123+ # os.waitstatus_to_exitcode may raise an exception for invalid values
124+ self ._exitcode = None
101125
102126 def getfd (self ):
103127 self .ensure_running ()
0 commit comments