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