xref: /aosp_15_r20/prebuilts/build-tools/common/py3-stdlib/multiprocessing/util.py (revision cda5da8d549138a6648c5ee6d7a49cf8f4a657be)
1*cda5da8dSAndroid Build Coastguard Worker#
2*cda5da8dSAndroid Build Coastguard Worker# Module providing various facilities to other parts of the package
3*cda5da8dSAndroid Build Coastguard Worker#
4*cda5da8dSAndroid Build Coastguard Worker# multiprocessing/util.py
5*cda5da8dSAndroid Build Coastguard Worker#
6*cda5da8dSAndroid Build Coastguard Worker# Copyright (c) 2006-2008, R Oudkerk
7*cda5da8dSAndroid Build Coastguard Worker# Licensed to PSF under a Contributor Agreement.
8*cda5da8dSAndroid Build Coastguard Worker#
9*cda5da8dSAndroid Build Coastguard Worker
10*cda5da8dSAndroid Build Coastguard Workerimport os
11*cda5da8dSAndroid Build Coastguard Workerimport itertools
12*cda5da8dSAndroid Build Coastguard Workerimport sys
13*cda5da8dSAndroid Build Coastguard Workerimport weakref
14*cda5da8dSAndroid Build Coastguard Workerimport atexit
15*cda5da8dSAndroid Build Coastguard Workerimport threading        # we want threading to install it's
16*cda5da8dSAndroid Build Coastguard Worker                        # cleanup function before multiprocessing does
17*cda5da8dSAndroid Build Coastguard Workerfrom subprocess import _args_from_interpreter_flags
18*cda5da8dSAndroid Build Coastguard Worker
19*cda5da8dSAndroid Build Coastguard Workerfrom . import process
20*cda5da8dSAndroid Build Coastguard Worker
21*cda5da8dSAndroid Build Coastguard Worker__all__ = [
22*cda5da8dSAndroid Build Coastguard Worker    'sub_debug', 'debug', 'info', 'sub_warning', 'get_logger',
23*cda5da8dSAndroid Build Coastguard Worker    'log_to_stderr', 'get_temp_dir', 'register_after_fork',
24*cda5da8dSAndroid Build Coastguard Worker    'is_exiting', 'Finalize', 'ForkAwareThreadLock', 'ForkAwareLocal',
25*cda5da8dSAndroid Build Coastguard Worker    'close_all_fds_except', 'SUBDEBUG', 'SUBWARNING',
26*cda5da8dSAndroid Build Coastguard Worker    ]
27*cda5da8dSAndroid Build Coastguard Worker
28*cda5da8dSAndroid Build Coastguard Worker#
29*cda5da8dSAndroid Build Coastguard Worker# Logging
30*cda5da8dSAndroid Build Coastguard Worker#
31*cda5da8dSAndroid Build Coastguard Worker
32*cda5da8dSAndroid Build Coastguard WorkerNOTSET = 0
33*cda5da8dSAndroid Build Coastguard WorkerSUBDEBUG = 5
34*cda5da8dSAndroid Build Coastguard WorkerDEBUG = 10
35*cda5da8dSAndroid Build Coastguard WorkerINFO = 20
36*cda5da8dSAndroid Build Coastguard WorkerSUBWARNING = 25
37*cda5da8dSAndroid Build Coastguard Worker
38*cda5da8dSAndroid Build Coastguard WorkerLOGGER_NAME = 'multiprocessing'
39*cda5da8dSAndroid Build Coastguard WorkerDEFAULT_LOGGING_FORMAT = '[%(levelname)s/%(processName)s] %(message)s'
40*cda5da8dSAndroid Build Coastguard Worker
41*cda5da8dSAndroid Build Coastguard Worker_logger = None
42*cda5da8dSAndroid Build Coastguard Worker_log_to_stderr = False
43*cda5da8dSAndroid Build Coastguard Worker
44*cda5da8dSAndroid Build Coastguard Workerdef sub_debug(msg, *args):
45*cda5da8dSAndroid Build Coastguard Worker    if _logger:
46*cda5da8dSAndroid Build Coastguard Worker        _logger.log(SUBDEBUG, msg, *args)
47*cda5da8dSAndroid Build Coastguard Worker
48*cda5da8dSAndroid Build Coastguard Workerdef debug(msg, *args):
49*cda5da8dSAndroid Build Coastguard Worker    if _logger:
50*cda5da8dSAndroid Build Coastguard Worker        _logger.log(DEBUG, msg, *args)
51*cda5da8dSAndroid Build Coastguard Worker
52*cda5da8dSAndroid Build Coastguard Workerdef info(msg, *args):
53*cda5da8dSAndroid Build Coastguard Worker    if _logger:
54*cda5da8dSAndroid Build Coastguard Worker        _logger.log(INFO, msg, *args)
55*cda5da8dSAndroid Build Coastguard Worker
56*cda5da8dSAndroid Build Coastguard Workerdef sub_warning(msg, *args):
57*cda5da8dSAndroid Build Coastguard Worker    if _logger:
58*cda5da8dSAndroid Build Coastguard Worker        _logger.log(SUBWARNING, msg, *args)
59*cda5da8dSAndroid Build Coastguard Worker
60*cda5da8dSAndroid Build Coastguard Workerdef get_logger():
61*cda5da8dSAndroid Build Coastguard Worker    '''
62*cda5da8dSAndroid Build Coastguard Worker    Returns logger used by multiprocessing
63*cda5da8dSAndroid Build Coastguard Worker    '''
64*cda5da8dSAndroid Build Coastguard Worker    global _logger
65*cda5da8dSAndroid Build Coastguard Worker    import logging
66*cda5da8dSAndroid Build Coastguard Worker
67*cda5da8dSAndroid Build Coastguard Worker    logging._acquireLock()
68*cda5da8dSAndroid Build Coastguard Worker    try:
69*cda5da8dSAndroid Build Coastguard Worker        if not _logger:
70*cda5da8dSAndroid Build Coastguard Worker
71*cda5da8dSAndroid Build Coastguard Worker            _logger = logging.getLogger(LOGGER_NAME)
72*cda5da8dSAndroid Build Coastguard Worker            _logger.propagate = 0
73*cda5da8dSAndroid Build Coastguard Worker
74*cda5da8dSAndroid Build Coastguard Worker            # XXX multiprocessing should cleanup before logging
75*cda5da8dSAndroid Build Coastguard Worker            if hasattr(atexit, 'unregister'):
76*cda5da8dSAndroid Build Coastguard Worker                atexit.unregister(_exit_function)
77*cda5da8dSAndroid Build Coastguard Worker                atexit.register(_exit_function)
78*cda5da8dSAndroid Build Coastguard Worker            else:
79*cda5da8dSAndroid Build Coastguard Worker                atexit._exithandlers.remove((_exit_function, (), {}))
80*cda5da8dSAndroid Build Coastguard Worker                atexit._exithandlers.append((_exit_function, (), {}))
81*cda5da8dSAndroid Build Coastguard Worker
82*cda5da8dSAndroid Build Coastguard Worker    finally:
83*cda5da8dSAndroid Build Coastguard Worker        logging._releaseLock()
84*cda5da8dSAndroid Build Coastguard Worker
85*cda5da8dSAndroid Build Coastguard Worker    return _logger
86*cda5da8dSAndroid Build Coastguard Worker
87*cda5da8dSAndroid Build Coastguard Workerdef log_to_stderr(level=None):
88*cda5da8dSAndroid Build Coastguard Worker    '''
89*cda5da8dSAndroid Build Coastguard Worker    Turn on logging and add a handler which prints to stderr
90*cda5da8dSAndroid Build Coastguard Worker    '''
91*cda5da8dSAndroid Build Coastguard Worker    global _log_to_stderr
92*cda5da8dSAndroid Build Coastguard Worker    import logging
93*cda5da8dSAndroid Build Coastguard Worker
94*cda5da8dSAndroid Build Coastguard Worker    logger = get_logger()
95*cda5da8dSAndroid Build Coastguard Worker    formatter = logging.Formatter(DEFAULT_LOGGING_FORMAT)
96*cda5da8dSAndroid Build Coastguard Worker    handler = logging.StreamHandler()
97*cda5da8dSAndroid Build Coastguard Worker    handler.setFormatter(formatter)
98*cda5da8dSAndroid Build Coastguard Worker    logger.addHandler(handler)
99*cda5da8dSAndroid Build Coastguard Worker
100*cda5da8dSAndroid Build Coastguard Worker    if level:
101*cda5da8dSAndroid Build Coastguard Worker        logger.setLevel(level)
102*cda5da8dSAndroid Build Coastguard Worker    _log_to_stderr = True
103*cda5da8dSAndroid Build Coastguard Worker    return _logger
104*cda5da8dSAndroid Build Coastguard Worker
105*cda5da8dSAndroid Build Coastguard Worker
106*cda5da8dSAndroid Build Coastguard Worker# Abstract socket support
107*cda5da8dSAndroid Build Coastguard Worker
108*cda5da8dSAndroid Build Coastguard Workerdef _platform_supports_abstract_sockets():
109*cda5da8dSAndroid Build Coastguard Worker    if sys.platform == "linux":
110*cda5da8dSAndroid Build Coastguard Worker        return True
111*cda5da8dSAndroid Build Coastguard Worker    if hasattr(sys, 'getandroidapilevel'):
112*cda5da8dSAndroid Build Coastguard Worker        return True
113*cda5da8dSAndroid Build Coastguard Worker    return False
114*cda5da8dSAndroid Build Coastguard Worker
115*cda5da8dSAndroid Build Coastguard Worker
116*cda5da8dSAndroid Build Coastguard Workerdef is_abstract_socket_namespace(address):
117*cda5da8dSAndroid Build Coastguard Worker    if not address:
118*cda5da8dSAndroid Build Coastguard Worker        return False
119*cda5da8dSAndroid Build Coastguard Worker    if isinstance(address, bytes):
120*cda5da8dSAndroid Build Coastguard Worker        return address[0] == 0
121*cda5da8dSAndroid Build Coastguard Worker    elif isinstance(address, str):
122*cda5da8dSAndroid Build Coastguard Worker        return address[0] == "\0"
123*cda5da8dSAndroid Build Coastguard Worker    raise TypeError(f'address type of {address!r} unrecognized')
124*cda5da8dSAndroid Build Coastguard Worker
125*cda5da8dSAndroid Build Coastguard Worker
126*cda5da8dSAndroid Build Coastguard Workerabstract_sockets_supported = _platform_supports_abstract_sockets()
127*cda5da8dSAndroid Build Coastguard Worker
128*cda5da8dSAndroid Build Coastguard Worker#
129*cda5da8dSAndroid Build Coastguard Worker# Function returning a temp directory which will be removed on exit
130*cda5da8dSAndroid Build Coastguard Worker#
131*cda5da8dSAndroid Build Coastguard Worker
132*cda5da8dSAndroid Build Coastguard Workerdef _remove_temp_dir(rmtree, tempdir):
133*cda5da8dSAndroid Build Coastguard Worker    rmtree(tempdir)
134*cda5da8dSAndroid Build Coastguard Worker
135*cda5da8dSAndroid Build Coastguard Worker    current_process = process.current_process()
136*cda5da8dSAndroid Build Coastguard Worker    # current_process() can be None if the finalizer is called
137*cda5da8dSAndroid Build Coastguard Worker    # late during Python finalization
138*cda5da8dSAndroid Build Coastguard Worker    if current_process is not None:
139*cda5da8dSAndroid Build Coastguard Worker        current_process._config['tempdir'] = None
140*cda5da8dSAndroid Build Coastguard Worker
141*cda5da8dSAndroid Build Coastguard Workerdef get_temp_dir():
142*cda5da8dSAndroid Build Coastguard Worker    # get name of a temp directory which will be automatically cleaned up
143*cda5da8dSAndroid Build Coastguard Worker    tempdir = process.current_process()._config.get('tempdir')
144*cda5da8dSAndroid Build Coastguard Worker    if tempdir is None:
145*cda5da8dSAndroid Build Coastguard Worker        import shutil, tempfile
146*cda5da8dSAndroid Build Coastguard Worker        tempdir = tempfile.mkdtemp(prefix='pymp-')
147*cda5da8dSAndroid Build Coastguard Worker        info('created temp directory %s', tempdir)
148*cda5da8dSAndroid Build Coastguard Worker        # keep a strong reference to shutil.rmtree(), since the finalizer
149*cda5da8dSAndroid Build Coastguard Worker        # can be called late during Python shutdown
150*cda5da8dSAndroid Build Coastguard Worker        Finalize(None, _remove_temp_dir, args=(shutil.rmtree, tempdir),
151*cda5da8dSAndroid Build Coastguard Worker                 exitpriority=-100)
152*cda5da8dSAndroid Build Coastguard Worker        process.current_process()._config['tempdir'] = tempdir
153*cda5da8dSAndroid Build Coastguard Worker    return tempdir
154*cda5da8dSAndroid Build Coastguard Worker
155*cda5da8dSAndroid Build Coastguard Worker#
156*cda5da8dSAndroid Build Coastguard Worker# Support for reinitialization of objects when bootstrapping a child process
157*cda5da8dSAndroid Build Coastguard Worker#
158*cda5da8dSAndroid Build Coastguard Worker
159*cda5da8dSAndroid Build Coastguard Worker_afterfork_registry = weakref.WeakValueDictionary()
160*cda5da8dSAndroid Build Coastguard Worker_afterfork_counter = itertools.count()
161*cda5da8dSAndroid Build Coastguard Worker
162*cda5da8dSAndroid Build Coastguard Workerdef _run_after_forkers():
163*cda5da8dSAndroid Build Coastguard Worker    items = list(_afterfork_registry.items())
164*cda5da8dSAndroid Build Coastguard Worker    items.sort()
165*cda5da8dSAndroid Build Coastguard Worker    for (index, ident, func), obj in items:
166*cda5da8dSAndroid Build Coastguard Worker        try:
167*cda5da8dSAndroid Build Coastguard Worker            func(obj)
168*cda5da8dSAndroid Build Coastguard Worker        except Exception as e:
169*cda5da8dSAndroid Build Coastguard Worker            info('after forker raised exception %s', e)
170*cda5da8dSAndroid Build Coastguard Worker
171*cda5da8dSAndroid Build Coastguard Workerdef register_after_fork(obj, func):
172*cda5da8dSAndroid Build Coastguard Worker    _afterfork_registry[(next(_afterfork_counter), id(obj), func)] = obj
173*cda5da8dSAndroid Build Coastguard Worker
174*cda5da8dSAndroid Build Coastguard Worker#
175*cda5da8dSAndroid Build Coastguard Worker# Finalization using weakrefs
176*cda5da8dSAndroid Build Coastguard Worker#
177*cda5da8dSAndroid Build Coastguard Worker
178*cda5da8dSAndroid Build Coastguard Worker_finalizer_registry = {}
179*cda5da8dSAndroid Build Coastguard Worker_finalizer_counter = itertools.count()
180*cda5da8dSAndroid Build Coastguard Worker
181*cda5da8dSAndroid Build Coastguard Worker
182*cda5da8dSAndroid Build Coastguard Workerclass Finalize(object):
183*cda5da8dSAndroid Build Coastguard Worker    '''
184*cda5da8dSAndroid Build Coastguard Worker    Class which supports object finalization using weakrefs
185*cda5da8dSAndroid Build Coastguard Worker    '''
186*cda5da8dSAndroid Build Coastguard Worker    def __init__(self, obj, callback, args=(), kwargs=None, exitpriority=None):
187*cda5da8dSAndroid Build Coastguard Worker        if (exitpriority is not None) and not isinstance(exitpriority,int):
188*cda5da8dSAndroid Build Coastguard Worker            raise TypeError(
189*cda5da8dSAndroid Build Coastguard Worker                "Exitpriority ({0!r}) must be None or int, not {1!s}".format(
190*cda5da8dSAndroid Build Coastguard Worker                    exitpriority, type(exitpriority)))
191*cda5da8dSAndroid Build Coastguard Worker
192*cda5da8dSAndroid Build Coastguard Worker        if obj is not None:
193*cda5da8dSAndroid Build Coastguard Worker            self._weakref = weakref.ref(obj, self)
194*cda5da8dSAndroid Build Coastguard Worker        elif exitpriority is None:
195*cda5da8dSAndroid Build Coastguard Worker            raise ValueError("Without object, exitpriority cannot be None")
196*cda5da8dSAndroid Build Coastguard Worker
197*cda5da8dSAndroid Build Coastguard Worker        self._callback = callback
198*cda5da8dSAndroid Build Coastguard Worker        self._args = args
199*cda5da8dSAndroid Build Coastguard Worker        self._kwargs = kwargs or {}
200*cda5da8dSAndroid Build Coastguard Worker        self._key = (exitpriority, next(_finalizer_counter))
201*cda5da8dSAndroid Build Coastguard Worker        self._pid = os.getpid()
202*cda5da8dSAndroid Build Coastguard Worker
203*cda5da8dSAndroid Build Coastguard Worker        _finalizer_registry[self._key] = self
204*cda5da8dSAndroid Build Coastguard Worker
205*cda5da8dSAndroid Build Coastguard Worker    def __call__(self, wr=None,
206*cda5da8dSAndroid Build Coastguard Worker                 # Need to bind these locally because the globals can have
207*cda5da8dSAndroid Build Coastguard Worker                 # been cleared at shutdown
208*cda5da8dSAndroid Build Coastguard Worker                 _finalizer_registry=_finalizer_registry,
209*cda5da8dSAndroid Build Coastguard Worker                 sub_debug=sub_debug, getpid=os.getpid):
210*cda5da8dSAndroid Build Coastguard Worker        '''
211*cda5da8dSAndroid Build Coastguard Worker        Run the callback unless it has already been called or cancelled
212*cda5da8dSAndroid Build Coastguard Worker        '''
213*cda5da8dSAndroid Build Coastguard Worker        try:
214*cda5da8dSAndroid Build Coastguard Worker            del _finalizer_registry[self._key]
215*cda5da8dSAndroid Build Coastguard Worker        except KeyError:
216*cda5da8dSAndroid Build Coastguard Worker            sub_debug('finalizer no longer registered')
217*cda5da8dSAndroid Build Coastguard Worker        else:
218*cda5da8dSAndroid Build Coastguard Worker            if self._pid != getpid():
219*cda5da8dSAndroid Build Coastguard Worker                sub_debug('finalizer ignored because different process')
220*cda5da8dSAndroid Build Coastguard Worker                res = None
221*cda5da8dSAndroid Build Coastguard Worker            else:
222*cda5da8dSAndroid Build Coastguard Worker                sub_debug('finalizer calling %s with args %s and kwargs %s',
223*cda5da8dSAndroid Build Coastguard Worker                          self._callback, self._args, self._kwargs)
224*cda5da8dSAndroid Build Coastguard Worker                res = self._callback(*self._args, **self._kwargs)
225*cda5da8dSAndroid Build Coastguard Worker            self._weakref = self._callback = self._args = \
226*cda5da8dSAndroid Build Coastguard Worker                            self._kwargs = self._key = None
227*cda5da8dSAndroid Build Coastguard Worker            return res
228*cda5da8dSAndroid Build Coastguard Worker
229*cda5da8dSAndroid Build Coastguard Worker    def cancel(self):
230*cda5da8dSAndroid Build Coastguard Worker        '''
231*cda5da8dSAndroid Build Coastguard Worker        Cancel finalization of the object
232*cda5da8dSAndroid Build Coastguard Worker        '''
233*cda5da8dSAndroid Build Coastguard Worker        try:
234*cda5da8dSAndroid Build Coastguard Worker            del _finalizer_registry[self._key]
235*cda5da8dSAndroid Build Coastguard Worker        except KeyError:
236*cda5da8dSAndroid Build Coastguard Worker            pass
237*cda5da8dSAndroid Build Coastguard Worker        else:
238*cda5da8dSAndroid Build Coastguard Worker            self._weakref = self._callback = self._args = \
239*cda5da8dSAndroid Build Coastguard Worker                            self._kwargs = self._key = None
240*cda5da8dSAndroid Build Coastguard Worker
241*cda5da8dSAndroid Build Coastguard Worker    def still_active(self):
242*cda5da8dSAndroid Build Coastguard Worker        '''
243*cda5da8dSAndroid Build Coastguard Worker        Return whether this finalizer is still waiting to invoke callback
244*cda5da8dSAndroid Build Coastguard Worker        '''
245*cda5da8dSAndroid Build Coastguard Worker        return self._key in _finalizer_registry
246*cda5da8dSAndroid Build Coastguard Worker
247*cda5da8dSAndroid Build Coastguard Worker    def __repr__(self):
248*cda5da8dSAndroid Build Coastguard Worker        try:
249*cda5da8dSAndroid Build Coastguard Worker            obj = self._weakref()
250*cda5da8dSAndroid Build Coastguard Worker        except (AttributeError, TypeError):
251*cda5da8dSAndroid Build Coastguard Worker            obj = None
252*cda5da8dSAndroid Build Coastguard Worker
253*cda5da8dSAndroid Build Coastguard Worker        if obj is None:
254*cda5da8dSAndroid Build Coastguard Worker            return '<%s object, dead>' % self.__class__.__name__
255*cda5da8dSAndroid Build Coastguard Worker
256*cda5da8dSAndroid Build Coastguard Worker        x = '<%s object, callback=%s' % (
257*cda5da8dSAndroid Build Coastguard Worker                self.__class__.__name__,
258*cda5da8dSAndroid Build Coastguard Worker                getattr(self._callback, '__name__', self._callback))
259*cda5da8dSAndroid Build Coastguard Worker        if self._args:
260*cda5da8dSAndroid Build Coastguard Worker            x += ', args=' + str(self._args)
261*cda5da8dSAndroid Build Coastguard Worker        if self._kwargs:
262*cda5da8dSAndroid Build Coastguard Worker            x += ', kwargs=' + str(self._kwargs)
263*cda5da8dSAndroid Build Coastguard Worker        if self._key[0] is not None:
264*cda5da8dSAndroid Build Coastguard Worker            x += ', exitpriority=' + str(self._key[0])
265*cda5da8dSAndroid Build Coastguard Worker        return x + '>'
266*cda5da8dSAndroid Build Coastguard Worker
267*cda5da8dSAndroid Build Coastguard Worker
268*cda5da8dSAndroid Build Coastguard Workerdef _run_finalizers(minpriority=None):
269*cda5da8dSAndroid Build Coastguard Worker    '''
270*cda5da8dSAndroid Build Coastguard Worker    Run all finalizers whose exit priority is not None and at least minpriority
271*cda5da8dSAndroid Build Coastguard Worker
272*cda5da8dSAndroid Build Coastguard Worker    Finalizers with highest priority are called first; finalizers with
273*cda5da8dSAndroid Build Coastguard Worker    the same priority will be called in reverse order of creation.
274*cda5da8dSAndroid Build Coastguard Worker    '''
275*cda5da8dSAndroid Build Coastguard Worker    if _finalizer_registry is None:
276*cda5da8dSAndroid Build Coastguard Worker        # This function may be called after this module's globals are
277*cda5da8dSAndroid Build Coastguard Worker        # destroyed.  See the _exit_function function in this module for more
278*cda5da8dSAndroid Build Coastguard Worker        # notes.
279*cda5da8dSAndroid Build Coastguard Worker        return
280*cda5da8dSAndroid Build Coastguard Worker
281*cda5da8dSAndroid Build Coastguard Worker    if minpriority is None:
282*cda5da8dSAndroid Build Coastguard Worker        f = lambda p : p[0] is not None
283*cda5da8dSAndroid Build Coastguard Worker    else:
284*cda5da8dSAndroid Build Coastguard Worker        f = lambda p : p[0] is not None and p[0] >= minpriority
285*cda5da8dSAndroid Build Coastguard Worker
286*cda5da8dSAndroid Build Coastguard Worker    # Careful: _finalizer_registry may be mutated while this function
287*cda5da8dSAndroid Build Coastguard Worker    # is running (either by a GC run or by another thread).
288*cda5da8dSAndroid Build Coastguard Worker
289*cda5da8dSAndroid Build Coastguard Worker    # list(_finalizer_registry) should be atomic, while
290*cda5da8dSAndroid Build Coastguard Worker    # list(_finalizer_registry.items()) is not.
291*cda5da8dSAndroid Build Coastguard Worker    keys = [key for key in list(_finalizer_registry) if f(key)]
292*cda5da8dSAndroid Build Coastguard Worker    keys.sort(reverse=True)
293*cda5da8dSAndroid Build Coastguard Worker
294*cda5da8dSAndroid Build Coastguard Worker    for key in keys:
295*cda5da8dSAndroid Build Coastguard Worker        finalizer = _finalizer_registry.get(key)
296*cda5da8dSAndroid Build Coastguard Worker        # key may have been removed from the registry
297*cda5da8dSAndroid Build Coastguard Worker        if finalizer is not None:
298*cda5da8dSAndroid Build Coastguard Worker            sub_debug('calling %s', finalizer)
299*cda5da8dSAndroid Build Coastguard Worker            try:
300*cda5da8dSAndroid Build Coastguard Worker                finalizer()
301*cda5da8dSAndroid Build Coastguard Worker            except Exception:
302*cda5da8dSAndroid Build Coastguard Worker                import traceback
303*cda5da8dSAndroid Build Coastguard Worker                traceback.print_exc()
304*cda5da8dSAndroid Build Coastguard Worker
305*cda5da8dSAndroid Build Coastguard Worker    if minpriority is None:
306*cda5da8dSAndroid Build Coastguard Worker        _finalizer_registry.clear()
307*cda5da8dSAndroid Build Coastguard Worker
308*cda5da8dSAndroid Build Coastguard Worker#
309*cda5da8dSAndroid Build Coastguard Worker# Clean up on exit
310*cda5da8dSAndroid Build Coastguard Worker#
311*cda5da8dSAndroid Build Coastguard Worker
312*cda5da8dSAndroid Build Coastguard Workerdef is_exiting():
313*cda5da8dSAndroid Build Coastguard Worker    '''
314*cda5da8dSAndroid Build Coastguard Worker    Returns true if the process is shutting down
315*cda5da8dSAndroid Build Coastguard Worker    '''
316*cda5da8dSAndroid Build Coastguard Worker    return _exiting or _exiting is None
317*cda5da8dSAndroid Build Coastguard Worker
318*cda5da8dSAndroid Build Coastguard Worker_exiting = False
319*cda5da8dSAndroid Build Coastguard Worker
320*cda5da8dSAndroid Build Coastguard Workerdef _exit_function(info=info, debug=debug, _run_finalizers=_run_finalizers,
321*cda5da8dSAndroid Build Coastguard Worker                   active_children=process.active_children,
322*cda5da8dSAndroid Build Coastguard Worker                   current_process=process.current_process):
323*cda5da8dSAndroid Build Coastguard Worker    # We hold on to references to functions in the arglist due to the
324*cda5da8dSAndroid Build Coastguard Worker    # situation described below, where this function is called after this
325*cda5da8dSAndroid Build Coastguard Worker    # module's globals are destroyed.
326*cda5da8dSAndroid Build Coastguard Worker
327*cda5da8dSAndroid Build Coastguard Worker    global _exiting
328*cda5da8dSAndroid Build Coastguard Worker
329*cda5da8dSAndroid Build Coastguard Worker    if not _exiting:
330*cda5da8dSAndroid Build Coastguard Worker        _exiting = True
331*cda5da8dSAndroid Build Coastguard Worker
332*cda5da8dSAndroid Build Coastguard Worker        info('process shutting down')
333*cda5da8dSAndroid Build Coastguard Worker        debug('running all "atexit" finalizers with priority >= 0')
334*cda5da8dSAndroid Build Coastguard Worker        _run_finalizers(0)
335*cda5da8dSAndroid Build Coastguard Worker
336*cda5da8dSAndroid Build Coastguard Worker        if current_process() is not None:
337*cda5da8dSAndroid Build Coastguard Worker            # We check if the current process is None here because if
338*cda5da8dSAndroid Build Coastguard Worker            # it's None, any call to ``active_children()`` will raise
339*cda5da8dSAndroid Build Coastguard Worker            # an AttributeError (active_children winds up trying to
340*cda5da8dSAndroid Build Coastguard Worker            # get attributes from util._current_process).  One
341*cda5da8dSAndroid Build Coastguard Worker            # situation where this can happen is if someone has
342*cda5da8dSAndroid Build Coastguard Worker            # manipulated sys.modules, causing this module to be
343*cda5da8dSAndroid Build Coastguard Worker            # garbage collected.  The destructor for the module type
344*cda5da8dSAndroid Build Coastguard Worker            # then replaces all values in the module dict with None.
345*cda5da8dSAndroid Build Coastguard Worker            # For instance, after setuptools runs a test it replaces
346*cda5da8dSAndroid Build Coastguard Worker            # sys.modules with a copy created earlier.  See issues
347*cda5da8dSAndroid Build Coastguard Worker            # #9775 and #15881.  Also related: #4106, #9205, and
348*cda5da8dSAndroid Build Coastguard Worker            # #9207.
349*cda5da8dSAndroid Build Coastguard Worker
350*cda5da8dSAndroid Build Coastguard Worker            for p in active_children():
351*cda5da8dSAndroid Build Coastguard Worker                if p.daemon:
352*cda5da8dSAndroid Build Coastguard Worker                    info('calling terminate() for daemon %s', p.name)
353*cda5da8dSAndroid Build Coastguard Worker                    p._popen.terminate()
354*cda5da8dSAndroid Build Coastguard Worker
355*cda5da8dSAndroid Build Coastguard Worker            for p in active_children():
356*cda5da8dSAndroid Build Coastguard Worker                info('calling join() for process %s', p.name)
357*cda5da8dSAndroid Build Coastguard Worker                p.join()
358*cda5da8dSAndroid Build Coastguard Worker
359*cda5da8dSAndroid Build Coastguard Worker        debug('running the remaining "atexit" finalizers')
360*cda5da8dSAndroid Build Coastguard Worker        _run_finalizers()
361*cda5da8dSAndroid Build Coastguard Worker
362*cda5da8dSAndroid Build Coastguard Workeratexit.register(_exit_function)
363*cda5da8dSAndroid Build Coastguard Worker
364*cda5da8dSAndroid Build Coastguard Worker#
365*cda5da8dSAndroid Build Coastguard Worker# Some fork aware types
366*cda5da8dSAndroid Build Coastguard Worker#
367*cda5da8dSAndroid Build Coastguard Worker
368*cda5da8dSAndroid Build Coastguard Workerclass ForkAwareThreadLock(object):
369*cda5da8dSAndroid Build Coastguard Worker    def __init__(self):
370*cda5da8dSAndroid Build Coastguard Worker        self._lock = threading.Lock()
371*cda5da8dSAndroid Build Coastguard Worker        self.acquire = self._lock.acquire
372*cda5da8dSAndroid Build Coastguard Worker        self.release = self._lock.release
373*cda5da8dSAndroid Build Coastguard Worker        register_after_fork(self, ForkAwareThreadLock._at_fork_reinit)
374*cda5da8dSAndroid Build Coastguard Worker
375*cda5da8dSAndroid Build Coastguard Worker    def _at_fork_reinit(self):
376*cda5da8dSAndroid Build Coastguard Worker        self._lock._at_fork_reinit()
377*cda5da8dSAndroid Build Coastguard Worker
378*cda5da8dSAndroid Build Coastguard Worker    def __enter__(self):
379*cda5da8dSAndroid Build Coastguard Worker        return self._lock.__enter__()
380*cda5da8dSAndroid Build Coastguard Worker
381*cda5da8dSAndroid Build Coastguard Worker    def __exit__(self, *args):
382*cda5da8dSAndroid Build Coastguard Worker        return self._lock.__exit__(*args)
383*cda5da8dSAndroid Build Coastguard Worker
384*cda5da8dSAndroid Build Coastguard Worker
385*cda5da8dSAndroid Build Coastguard Workerclass ForkAwareLocal(threading.local):
386*cda5da8dSAndroid Build Coastguard Worker    def __init__(self):
387*cda5da8dSAndroid Build Coastguard Worker        register_after_fork(self, lambda obj : obj.__dict__.clear())
388*cda5da8dSAndroid Build Coastguard Worker    def __reduce__(self):
389*cda5da8dSAndroid Build Coastguard Worker        return type(self), ()
390*cda5da8dSAndroid Build Coastguard Worker
391*cda5da8dSAndroid Build Coastguard Worker#
392*cda5da8dSAndroid Build Coastguard Worker# Close fds except those specified
393*cda5da8dSAndroid Build Coastguard Worker#
394*cda5da8dSAndroid Build Coastguard Worker
395*cda5da8dSAndroid Build Coastguard Workertry:
396*cda5da8dSAndroid Build Coastguard Worker    MAXFD = os.sysconf("SC_OPEN_MAX")
397*cda5da8dSAndroid Build Coastguard Workerexcept Exception:
398*cda5da8dSAndroid Build Coastguard Worker    MAXFD = 256
399*cda5da8dSAndroid Build Coastguard Worker
400*cda5da8dSAndroid Build Coastguard Workerdef close_all_fds_except(fds):
401*cda5da8dSAndroid Build Coastguard Worker    fds = list(fds) + [-1, MAXFD]
402*cda5da8dSAndroid Build Coastguard Worker    fds.sort()
403*cda5da8dSAndroid Build Coastguard Worker    assert fds[-1] == MAXFD, 'fd too large'
404*cda5da8dSAndroid Build Coastguard Worker    for i in range(len(fds) - 1):
405*cda5da8dSAndroid Build Coastguard Worker        os.closerange(fds[i]+1, fds[i+1])
406*cda5da8dSAndroid Build Coastguard Worker#
407*cda5da8dSAndroid Build Coastguard Worker# Close sys.stdin and replace stdin with os.devnull
408*cda5da8dSAndroid Build Coastguard Worker#
409*cda5da8dSAndroid Build Coastguard Worker
410*cda5da8dSAndroid Build Coastguard Workerdef _close_stdin():
411*cda5da8dSAndroid Build Coastguard Worker    if sys.stdin is None:
412*cda5da8dSAndroid Build Coastguard Worker        return
413*cda5da8dSAndroid Build Coastguard Worker
414*cda5da8dSAndroid Build Coastguard Worker    try:
415*cda5da8dSAndroid Build Coastguard Worker        sys.stdin.close()
416*cda5da8dSAndroid Build Coastguard Worker    except (OSError, ValueError):
417*cda5da8dSAndroid Build Coastguard Worker        pass
418*cda5da8dSAndroid Build Coastguard Worker
419*cda5da8dSAndroid Build Coastguard Worker    try:
420*cda5da8dSAndroid Build Coastguard Worker        fd = os.open(os.devnull, os.O_RDONLY)
421*cda5da8dSAndroid Build Coastguard Worker        try:
422*cda5da8dSAndroid Build Coastguard Worker            sys.stdin = open(fd, encoding="utf-8", closefd=False)
423*cda5da8dSAndroid Build Coastguard Worker        except:
424*cda5da8dSAndroid Build Coastguard Worker            os.close(fd)
425*cda5da8dSAndroid Build Coastguard Worker            raise
426*cda5da8dSAndroid Build Coastguard Worker    except (OSError, ValueError):
427*cda5da8dSAndroid Build Coastguard Worker        pass
428*cda5da8dSAndroid Build Coastguard Worker
429*cda5da8dSAndroid Build Coastguard Worker#
430*cda5da8dSAndroid Build Coastguard Worker# Flush standard streams, if any
431*cda5da8dSAndroid Build Coastguard Worker#
432*cda5da8dSAndroid Build Coastguard Worker
433*cda5da8dSAndroid Build Coastguard Workerdef _flush_std_streams():
434*cda5da8dSAndroid Build Coastguard Worker    try:
435*cda5da8dSAndroid Build Coastguard Worker        sys.stdout.flush()
436*cda5da8dSAndroid Build Coastguard Worker    except (AttributeError, ValueError):
437*cda5da8dSAndroid Build Coastguard Worker        pass
438*cda5da8dSAndroid Build Coastguard Worker    try:
439*cda5da8dSAndroid Build Coastguard Worker        sys.stderr.flush()
440*cda5da8dSAndroid Build Coastguard Worker    except (AttributeError, ValueError):
441*cda5da8dSAndroid Build Coastguard Worker        pass
442*cda5da8dSAndroid Build Coastguard Worker
443*cda5da8dSAndroid Build Coastguard Worker#
444*cda5da8dSAndroid Build Coastguard Worker# Start a program with only specified fds kept open
445*cda5da8dSAndroid Build Coastguard Worker#
446*cda5da8dSAndroid Build Coastguard Worker
447*cda5da8dSAndroid Build Coastguard Workerdef spawnv_passfds(path, args, passfds):
448*cda5da8dSAndroid Build Coastguard Worker    import _posixsubprocess
449*cda5da8dSAndroid Build Coastguard Worker    import subprocess
450*cda5da8dSAndroid Build Coastguard Worker    passfds = tuple(sorted(map(int, passfds)))
451*cda5da8dSAndroid Build Coastguard Worker    errpipe_read, errpipe_write = os.pipe()
452*cda5da8dSAndroid Build Coastguard Worker    try:
453*cda5da8dSAndroid Build Coastguard Worker        return _posixsubprocess.fork_exec(
454*cda5da8dSAndroid Build Coastguard Worker            args, [path], True, passfds, None, None,
455*cda5da8dSAndroid Build Coastguard Worker            -1, -1, -1, -1, -1, -1, errpipe_read, errpipe_write,
456*cda5da8dSAndroid Build Coastguard Worker            False, False, -1, None, None, None, -1, None,
457*cda5da8dSAndroid Build Coastguard Worker            subprocess._USE_VFORK)
458*cda5da8dSAndroid Build Coastguard Worker    finally:
459*cda5da8dSAndroid Build Coastguard Worker        os.close(errpipe_read)
460*cda5da8dSAndroid Build Coastguard Worker        os.close(errpipe_write)
461*cda5da8dSAndroid Build Coastguard Worker
462*cda5da8dSAndroid Build Coastguard Worker
463*cda5da8dSAndroid Build Coastguard Workerdef close_fds(*fds):
464*cda5da8dSAndroid Build Coastguard Worker    """Close each file descriptor given as an argument"""
465*cda5da8dSAndroid Build Coastguard Worker    for fd in fds:
466*cda5da8dSAndroid Build Coastguard Worker        os.close(fd)
467*cda5da8dSAndroid Build Coastguard Worker
468*cda5da8dSAndroid Build Coastguard Worker
469*cda5da8dSAndroid Build Coastguard Workerdef _cleanup_tests():
470*cda5da8dSAndroid Build Coastguard Worker    """Cleanup multiprocessing resources when multiprocessing tests
471*cda5da8dSAndroid Build Coastguard Worker    completed."""
472*cda5da8dSAndroid Build Coastguard Worker
473*cda5da8dSAndroid Build Coastguard Worker    from test import support
474*cda5da8dSAndroid Build Coastguard Worker
475*cda5da8dSAndroid Build Coastguard Worker    # cleanup multiprocessing
476*cda5da8dSAndroid Build Coastguard Worker    process._cleanup()
477*cda5da8dSAndroid Build Coastguard Worker
478*cda5da8dSAndroid Build Coastguard Worker    # Stop the ForkServer process if it's running
479*cda5da8dSAndroid Build Coastguard Worker    from multiprocessing import forkserver
480*cda5da8dSAndroid Build Coastguard Worker    forkserver._forkserver._stop()
481*cda5da8dSAndroid Build Coastguard Worker
482*cda5da8dSAndroid Build Coastguard Worker    # Stop the ResourceTracker process if it's running
483*cda5da8dSAndroid Build Coastguard Worker    from multiprocessing import resource_tracker
484*cda5da8dSAndroid Build Coastguard Worker    resource_tracker._resource_tracker._stop()
485*cda5da8dSAndroid Build Coastguard Worker
486*cda5da8dSAndroid Build Coastguard Worker    # bpo-37421: Explicitly call _run_finalizers() to remove immediately
487*cda5da8dSAndroid Build Coastguard Worker    # temporary directories created by multiprocessing.util.get_temp_dir().
488*cda5da8dSAndroid Build Coastguard Worker    _run_finalizers()
489*cda5da8dSAndroid Build Coastguard Worker    support.gc_collect()
490*cda5da8dSAndroid Build Coastguard Worker
491*cda5da8dSAndroid Build Coastguard Worker    support.reap_children()
492