util.py revision ebdcd859e59ed16a79dea94291c0be3a87640a08
1e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson#
2e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson# Module providing various facilities to other parts of the package
3e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson#
4e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson# multiprocessing/util.py
5e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson#
63fc969a4a26f0bd94f1412b45da5e8cf3c6eaf1eR. David Murray# Copyright (c) 2006-2008, R Oudkerk
73e268aac3b1b3c89925b59dae7a213b94bc114b8Richard Oudkerk# Licensed to PSF under a Contributor Agreement.
8e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson#
9e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson
1077c84f2defb0013e28d262be237142379a1407feRichard Oudkerkimport sys
11176f07dadf80c27348486fdd8017fabbb30da842Antoine Pitrouimport functools
12e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Petersonimport itertools
13e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Petersonimport weakref
14e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Petersonimport atexit
15e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Petersonimport threading        # we want threading to install it's
16e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson                        # cleanup function before multiprocessing does
17ebdcd859e59ed16a79dea94291c0be3a87640a08Antoine Pitroufrom subprocess import _args_from_interpreter_flags
18e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson
19e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Petersonfrom multiprocessing.process import current_process, active_children
20e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson
21e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson__all__ = [
22e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson    'sub_debug', 'debug', 'info', 'sub_warning', 'get_logger',
23e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson    'log_to_stderr', 'get_temp_dir', 'register_after_fork',
2441faa543b66431ee5b8c79f70a40ef267615050bJesse Noller    'is_exiting', 'Finalize', 'ForkAwareThreadLock', 'ForkAwareLocal',
2541faa543b66431ee5b8c79f70a40ef267615050bJesse Noller    'SUBDEBUG', 'SUBWARNING',
26e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson    ]
27e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson
28e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson#
29e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson# Logging
30e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson#
31e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson
32e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin PetersonNOTSET = 0
33e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin PetersonSUBDEBUG = 5
34e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin PetersonDEBUG = 10
35e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin PetersonINFO = 20
36e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin PetersonSUBWARNING = 25
37e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson
38e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin PetersonLOGGER_NAME = 'multiprocessing'
39e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin PetersonDEFAULT_LOGGING_FORMAT = '[%(levelname)s/%(processName)s] %(message)s'
40e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson
41e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson_logger = None
42e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson_log_to_stderr = False
43e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson
44e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Petersondef sub_debug(msg, *args):
45e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson    if _logger:
46e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson        _logger.log(SUBDEBUG, msg, *args)
47e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson
48e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Petersondef debug(msg, *args):
49e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson    if _logger:
50e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson        _logger.log(DEBUG, msg, *args)
51e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson
52e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Petersondef info(msg, *args):
53e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson    if _logger:
54e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson        _logger.log(INFO, msg, *args)
55e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson
56e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Petersondef sub_warning(msg, *args):
57e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson    if _logger:
58e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson        _logger.log(SUBWARNING, msg, *args)
59e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson
60e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Petersondef get_logger():
61e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson    '''
62e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson    Returns logger used by multiprocessing
63e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson    '''
64e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson    global _logger
6504842a84c31d82d9c2255e6575344412c58e518eFlorent Xicluna    import logging
66e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson
6741faa543b66431ee5b8c79f70a40ef267615050bJesse Noller    logging._acquireLock()
6841faa543b66431ee5b8c79f70a40ef267615050bJesse Noller    try:
6941faa543b66431ee5b8c79f70a40ef267615050bJesse Noller        if not _logger:
70e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson
7141faa543b66431ee5b8c79f70a40ef267615050bJesse Noller            _logger = logging.getLogger(LOGGER_NAME)
7241faa543b66431ee5b8c79f70a40ef267615050bJesse Noller            _logger.propagate = 0
7341faa543b66431ee5b8c79f70a40ef267615050bJesse Noller            logging.addLevelName(SUBDEBUG, 'SUBDEBUG')
7441faa543b66431ee5b8c79f70a40ef267615050bJesse Noller            logging.addLevelName(SUBWARNING, 'SUBWARNING')
75e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson
7641faa543b66431ee5b8c79f70a40ef267615050bJesse Noller            # XXX multiprocessing should cleanup before logging
7741faa543b66431ee5b8c79f70a40ef267615050bJesse Noller            if hasattr(atexit, 'unregister'):
7841faa543b66431ee5b8c79f70a40ef267615050bJesse Noller                atexit.unregister(_exit_function)
7941faa543b66431ee5b8c79f70a40ef267615050bJesse Noller                atexit.register(_exit_function)
8041faa543b66431ee5b8c79f70a40ef267615050bJesse Noller            else:
8141faa543b66431ee5b8c79f70a40ef267615050bJesse Noller                atexit._exithandlers.remove((_exit_function, (), {}))
8241faa543b66431ee5b8c79f70a40ef267615050bJesse Noller                atexit._exithandlers.append((_exit_function, (), {}))
8341faa543b66431ee5b8c79f70a40ef267615050bJesse Noller
8441faa543b66431ee5b8c79f70a40ef267615050bJesse Noller    finally:
8541faa543b66431ee5b8c79f70a40ef267615050bJesse Noller        logging._releaseLock()
86e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson
87e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson    return _logger
88e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson
89e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Petersondef log_to_stderr(level=None):
90e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson    '''
91e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson    Turn on logging and add a handler which prints to stderr
92e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson    '''
93e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson    global _log_to_stderr
94e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson    import logging
9541faa543b66431ee5b8c79f70a40ef267615050bJesse Noller
96e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson    logger = get_logger()
97e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson    formatter = logging.Formatter(DEFAULT_LOGGING_FORMAT)
98e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson    handler = logging.StreamHandler()
99e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson    handler.setFormatter(formatter)
100e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson    logger.addHandler(handler)
10141faa543b66431ee5b8c79f70a40ef267615050bJesse Noller
10241faa543b66431ee5b8c79f70a40ef267615050bJesse Noller    if level:
103e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson        logger.setLevel(level)
104e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson    _log_to_stderr = True
10541faa543b66431ee5b8c79f70a40ef267615050bJesse Noller    return _logger
106e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson
107e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson#
108e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson# Function returning a temp directory which will be removed on exit
109e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson#
110e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson
111e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Petersondef get_temp_dir():
112e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson    # get name of a temp directory which will be automatically cleaned up
113e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson    if current_process()._tempdir is None:
114e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson        import shutil, tempfile
115e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson        tempdir = tempfile.mkdtemp(prefix='pymp-')
116e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson        info('created temp directory %s', tempdir)
117e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson        Finalize(None, shutil.rmtree, args=[tempdir], exitpriority=-100)
118e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson        current_process()._tempdir = tempdir
119e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson    return current_process()._tempdir
120e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson
121e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson#
122e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson# Support for reinitialization of objects when bootstrapping a child process
123e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson#
124e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson
125e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson_afterfork_registry = weakref.WeakValueDictionary()
126e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson_afterfork_counter = itertools.count()
127e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson
128e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Petersondef _run_after_forkers():
129e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson    items = list(_afterfork_registry.items())
130e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson    items.sort()
131e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson    for (index, ident, func), obj in items:
132e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson        try:
133e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson            func(obj)
134e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson        except Exception as e:
135e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson            info('after forker raised exception %s', e)
136e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson
137e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Petersondef register_after_fork(obj, func):
138e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson    _afterfork_registry[(next(_afterfork_counter), id(obj), func)] = obj
139e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson
140e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson#
141e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson# Finalization using weakrefs
142e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson#
143e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson
144e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson_finalizer_registry = {}
145e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson_finalizer_counter = itertools.count()
146e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson
147e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson
148e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Petersonclass Finalize(object):
149e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson    '''
150e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson    Class which supports object finalization using weakrefs
151e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson    '''
152e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson    def __init__(self, obj, callback, args=(), kwargs=None, exitpriority=None):
153e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson        assert exitpriority is None or type(exitpriority) is int
154e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson
155e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson        if obj is not None:
156e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson            self._weakref = weakref.ref(obj, self)
157e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson        else:
158e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson            assert exitpriority is not None
159e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson
160e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson        self._callback = callback
161e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson        self._args = args
162e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson        self._kwargs = kwargs or {}
163e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson        self._key = (exitpriority, next(_finalizer_counter))
164e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson
165e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson        _finalizer_registry[self._key] = self
166e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson
16771a28a91744b5cf6f881769300818232750de6d2Antoine Pitrou    def __call__(self, wr=None,
16871a28a91744b5cf6f881769300818232750de6d2Antoine Pitrou                 # Need to bind these locally because the globals can have
16971a28a91744b5cf6f881769300818232750de6d2Antoine Pitrou                 # been cleared at shutdown
17071a28a91744b5cf6f881769300818232750de6d2Antoine Pitrou                 _finalizer_registry=_finalizer_registry,
17171a28a91744b5cf6f881769300818232750de6d2Antoine Pitrou                 sub_debug=sub_debug):
172e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson        '''
173e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson        Run the callback unless it has already been called or cancelled
174e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson        '''
175e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson        try:
176e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson            del _finalizer_registry[self._key]
177e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson        except KeyError:
178e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson            sub_debug('finalizer no longer registered')
179e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson        else:
180e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson            sub_debug('finalizer calling %s with args %s and kwargs %s',
181e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson                     self._callback, self._args, self._kwargs)
182e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson            res = self._callback(*self._args, **self._kwargs)
183e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson            self._weakref = self._callback = self._args = \
184e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson                            self._kwargs = self._key = None
185e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson            return res
186e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson
187e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson    def cancel(self):
188e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson        '''
189e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson        Cancel finalization of the object
190e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson        '''
191e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson        try:
192e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson            del _finalizer_registry[self._key]
193e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson        except KeyError:
194e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson            pass
195e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson        else:
196e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson            self._weakref = self._callback = self._args = \
197e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson                            self._kwargs = self._key = None
198e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson
199e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson    def still_active(self):
200e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson        '''
201e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson        Return whether this finalizer is still waiting to invoke callback
202e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson        '''
203e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson        return self._key in _finalizer_registry
204e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson
205e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson    def __repr__(self):
206e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson        try:
207e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson            obj = self._weakref()
208e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson        except (AttributeError, TypeError):
209e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson            obj = None
210e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson
211e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson        if obj is None:
212e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson            return '<Finalize object, dead>'
213e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson
214e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson        x = '<Finalize object, callback=%s' % \
215e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson            getattr(self._callback, '__name__', self._callback)
216e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson        if self._args:
217e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson            x += ', args=' + str(self._args)
218e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson        if self._kwargs:
219e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson            x += ', kwargs=' + str(self._kwargs)
220e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson        if self._key[0] is not None:
221e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson            x += ', exitprority=' + str(self._key[0])
222e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson        return x + '>'
223e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson
224e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson
225e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Petersondef _run_finalizers(minpriority=None):
226e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson    '''
227e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson    Run all finalizers whose exit priority is not None and at least minpriority
228e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson
229e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson    Finalizers with highest priority are called first; finalizers with
230e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson    the same priority will be called in reverse order of creation.
231e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson    '''
232e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson    if minpriority is None:
233e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson        f = lambda p : p[0][0] is not None
234e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson    else:
235e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson        f = lambda p : p[0][0] is not None and p[0][0] >= minpriority
236e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson
237e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson    items = [x for x in list(_finalizer_registry.items()) if f(x)]
238e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson    items.sort(reverse=True)
239e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson
240e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson    for key, finalizer in items:
241e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson        sub_debug('calling %s', finalizer)
242e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson        try:
243e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson            finalizer()
244e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson        except Exception:
245e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson            import traceback
246e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson            traceback.print_exc()
247e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson
248e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson    if minpriority is None:
249e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson        _finalizer_registry.clear()
250e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson
251e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson#
252e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson# Clean up on exit
253e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson#
254e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson
255e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Petersondef is_exiting():
256e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson    '''
257e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson    Returns true if the process is shutting down
258e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson    '''
259e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson    return _exiting or _exiting is None
260e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson
261e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson_exiting = False
262e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson
263e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Petersondef _exit_function():
264e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson    global _exiting
265e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson
266e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson    info('process shutting down')
267e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson    debug('running all "atexit" finalizers with priority >= 0')
268e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson    _run_finalizers(0)
269e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson
270e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson    for p in active_children():
271e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson        if p._daemonic:
27258ea9fedc825a91a3b153898afade19512bbde85Benjamin Peterson            info('calling terminate() for daemon %s', p.name)
273e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson            p._popen.terminate()
274e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson
275e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson    for p in active_children():
27658ea9fedc825a91a3b153898afade19512bbde85Benjamin Peterson        info('calling join() for process %s', p.name)
277e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson        p.join()
278e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson
279e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson    debug('running the remaining "atexit" finalizers')
280e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson    _run_finalizers()
281e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson
282e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Petersonatexit.register(_exit_function)
283e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson
284e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson#
285e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson# Some fork aware types
286e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson#
287e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson
288e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Petersonclass ForkAwareThreadLock(object):
289e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson    def __init__(self):
290e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson        self._lock = threading.Lock()
291e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson        self.acquire = self._lock.acquire
292e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson        self.release = self._lock.release
293e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson        register_after_fork(self, ForkAwareThreadLock.__init__)
294e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson
295e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Petersonclass ForkAwareLocal(threading.local):
296e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson    def __init__(self):
297e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson        register_after_fork(self, lambda obj : obj.__dict__.clear())
298e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson    def __reduce__(self):
299e711cafab13efc9c1fe6c5cd75826401445eb585Benjamin Peterson        return type(self), ()
30077c84f2defb0013e28d262be237142379a1407feRichard Oudkerk
301