| """Thread module emulating a subset of Java's threading model.""" | 
 |  | 
 | import sys as _sys | 
 | import _thread | 
 |  | 
 | from time import sleep as _sleep | 
 | try: | 
 |     from time import monotonic as _time | 
 | except ImportError: | 
 |     from time import time as _time | 
 | from traceback import format_exc as _format_exc | 
 | from _weakrefset import WeakSet | 
 |  | 
 | # Note regarding PEP 8 compliant names | 
 | #  This threading model was originally inspired by Java, and inherited | 
 | # the convention of camelCase function and method names from that | 
 | # language. Those original names are not in any imminent danger of | 
 | # being deprecated (even for Py3k),so this module provides them as an | 
 | # alias for the PEP 8 compliant names | 
 | # Note that using the new PEP 8 compliant names facilitates substitution | 
 | # with the multiprocessing module, which doesn't provide the old | 
 | # Java inspired names. | 
 |  | 
 | __all__ = ['active_count', 'Condition', 'current_thread', 'enumerate', 'Event', | 
 |            'Lock', 'RLock', 'Semaphore', 'BoundedSemaphore', 'Thread', 'Barrier', | 
 |            'Timer', 'ThreadError', 'setprofile', 'settrace', 'local', 'stack_size'] | 
 |  | 
 | # Rename some stuff so "from threading import *" is safe | 
 | _start_new_thread = _thread.start_new_thread | 
 | _allocate_lock = _thread.allocate_lock | 
 | get_ident = _thread.get_ident | 
 | ThreadError = _thread.error | 
 | try: | 
 |     _CRLock = _thread.RLock | 
 | except AttributeError: | 
 |     _CRLock = None | 
 | TIMEOUT_MAX = _thread.TIMEOUT_MAX | 
 | del _thread | 
 |  | 
 |  | 
 | # Support for profile and trace hooks | 
 |  | 
 | _profile_hook = None | 
 | _trace_hook = None | 
 |  | 
 | def setprofile(func): | 
 |     global _profile_hook | 
 |     _profile_hook = func | 
 |  | 
 | def settrace(func): | 
 |     global _trace_hook | 
 |     _trace_hook = func | 
 |  | 
 | # Synchronization classes | 
 |  | 
 | Lock = _allocate_lock | 
 |  | 
 | def RLock(*args, **kwargs): | 
 |     if _CRLock is None: | 
 |         return _PyRLock(*args, **kwargs) | 
 |     return _CRLock(*args, **kwargs) | 
 |  | 
 | class _RLock: | 
 |  | 
 |     def __init__(self): | 
 |         self._block = _allocate_lock() | 
 |         self._owner = None | 
 |         self._count = 0 | 
 |  | 
 |     def __repr__(self): | 
 |         owner = self._owner | 
 |         try: | 
 |             owner = _active[owner].name | 
 |         except KeyError: | 
 |             pass | 
 |         return "<%s owner=%r count=%d>" % ( | 
 |                 self.__class__.__name__, owner, self._count) | 
 |  | 
 |     def acquire(self, blocking=True, timeout=-1): | 
 |         me = get_ident() | 
 |         if self._owner == me: | 
 |             self._count = self._count + 1 | 
 |             return 1 | 
 |         rc = self._block.acquire(blocking, timeout) | 
 |         if rc: | 
 |             self._owner = me | 
 |             self._count = 1 | 
 |         return rc | 
 |  | 
 |     __enter__ = acquire | 
 |  | 
 |     def release(self): | 
 |         if self._owner != get_ident(): | 
 |             raise RuntimeError("cannot release un-acquired lock") | 
 |         self._count = count = self._count - 1 | 
 |         if not count: | 
 |             self._owner = None | 
 |             self._block.release() | 
 |  | 
 |     def __exit__(self, t, v, tb): | 
 |         self.release() | 
 |  | 
 |     # Internal methods used by condition variables | 
 |  | 
 |     def _acquire_restore(self, state): | 
 |         self._block.acquire() | 
 |         self._count, self._owner = state | 
 |  | 
 |     def _release_save(self): | 
 |         if self._count == 0: | 
 |             raise RuntimeError("cannot release un-acquired lock") | 
 |         count = self._count | 
 |         self._count = 0 | 
 |         owner = self._owner | 
 |         self._owner = None | 
 |         self._block.release() | 
 |         return (count, owner) | 
 |  | 
 |     def _is_owned(self): | 
 |         return self._owner == get_ident() | 
 |  | 
 | _PyRLock = _RLock | 
 |  | 
 |  | 
 | class Condition: | 
 |  | 
 |     def __init__(self, lock=None): | 
 |         if lock is None: | 
 |             lock = RLock() | 
 |         self._lock = lock | 
 |         # Export the lock's acquire() and release() methods | 
 |         self.acquire = lock.acquire | 
 |         self.release = lock.release | 
 |         # If the lock defines _release_save() and/or _acquire_restore(), | 
 |         # these override the default implementations (which just call | 
 |         # release() and acquire() on the lock).  Ditto for _is_owned(). | 
 |         try: | 
 |             self._release_save = lock._release_save | 
 |         except AttributeError: | 
 |             pass | 
 |         try: | 
 |             self._acquire_restore = lock._acquire_restore | 
 |         except AttributeError: | 
 |             pass | 
 |         try: | 
 |             self._is_owned = lock._is_owned | 
 |         except AttributeError: | 
 |             pass | 
 |         self._waiters = [] | 
 |  | 
 |     def __enter__(self): | 
 |         return self._lock.__enter__() | 
 |  | 
 |     def __exit__(self, *args): | 
 |         return self._lock.__exit__(*args) | 
 |  | 
 |     def __repr__(self): | 
 |         return "<Condition(%s, %d)>" % (self._lock, len(self._waiters)) | 
 |  | 
 |     def _release_save(self): | 
 |         self._lock.release()           # No state to save | 
 |  | 
 |     def _acquire_restore(self, x): | 
 |         self._lock.acquire()           # Ignore saved state | 
 |  | 
 |     def _is_owned(self): | 
 |         # Return True if lock is owned by current_thread. | 
 |         # This method is called only if __lock doesn't have _is_owned(). | 
 |         if self._lock.acquire(0): | 
 |             self._lock.release() | 
 |             return False | 
 |         else: | 
 |             return True | 
 |  | 
 |     def wait(self, timeout=None): | 
 |         if not self._is_owned(): | 
 |             raise RuntimeError("cannot wait on un-acquired lock") | 
 |         waiter = _allocate_lock() | 
 |         waiter.acquire() | 
 |         self._waiters.append(waiter) | 
 |         saved_state = self._release_save() | 
 |         try:    # restore state no matter what (e.g., KeyboardInterrupt) | 
 |             if timeout is None: | 
 |                 waiter.acquire() | 
 |                 gotit = True | 
 |             else: | 
 |                 if timeout > 0: | 
 |                     gotit = waiter.acquire(True, timeout) | 
 |                 else: | 
 |                     gotit = waiter.acquire(False) | 
 |                 if not gotit: | 
 |                     try: | 
 |                         self._waiters.remove(waiter) | 
 |                     except ValueError: | 
 |                         pass | 
 |             return gotit | 
 |         finally: | 
 |             self._acquire_restore(saved_state) | 
 |  | 
 |     def wait_for(self, predicate, timeout=None): | 
 |         endtime = None | 
 |         waittime = timeout | 
 |         result = predicate() | 
 |         while not result: | 
 |             if waittime is not None: | 
 |                 if endtime is None: | 
 |                     endtime = _time() + waittime | 
 |                 else: | 
 |                     waittime = endtime - _time() | 
 |                     if waittime <= 0: | 
 |                         break | 
 |             self.wait(waittime) | 
 |             result = predicate() | 
 |         return result | 
 |  | 
 |     def notify(self, n=1): | 
 |         if not self._is_owned(): | 
 |             raise RuntimeError("cannot notify on un-acquired lock") | 
 |         __waiters = self._waiters | 
 |         waiters = __waiters[:n] | 
 |         if not waiters: | 
 |             return | 
 |         for waiter in waiters: | 
 |             waiter.release() | 
 |             try: | 
 |                 __waiters.remove(waiter) | 
 |             except ValueError: | 
 |                 pass | 
 |  | 
 |     def notify_all(self): | 
 |         self.notify(len(self._waiters)) | 
 |  | 
 |     notifyAll = notify_all | 
 |  | 
 |  | 
 | class Semaphore: | 
 |  | 
 |     # After Tim Peters' semaphore class, but not quite the same (no maximum) | 
 |  | 
 |     def __init__(self, value=1): | 
 |         if value < 0: | 
 |             raise ValueError("semaphore initial value must be >= 0") | 
 |         self._cond = Condition(Lock()) | 
 |         self._value = value | 
 |  | 
 |     def acquire(self, blocking=True, timeout=None): | 
 |         if not blocking and timeout is not None: | 
 |             raise ValueError("can't specify timeout for non-blocking acquire") | 
 |         rc = False | 
 |         endtime = None | 
 |         with self._cond: | 
 |             while self._value == 0: | 
 |                 if not blocking: | 
 |                     break | 
 |                 if timeout is not None: | 
 |                     if endtime is None: | 
 |                         endtime = _time() + timeout | 
 |                     else: | 
 |                         timeout = endtime - _time() | 
 |                         if timeout <= 0: | 
 |                             break | 
 |                 self._cond.wait(timeout) | 
 |             else: | 
 |                 self._value = self._value - 1 | 
 |                 rc = True | 
 |         return rc | 
 |  | 
 |     __enter__ = acquire | 
 |  | 
 |     def release(self): | 
 |         with self._cond: | 
 |             self._value = self._value + 1 | 
 |             self._cond.notify() | 
 |  | 
 |     def __exit__(self, t, v, tb): | 
 |         self.release() | 
 |  | 
 |  | 
 | class BoundedSemaphore(Semaphore): | 
 |     """Semaphore that checks that # releases is <= # acquires""" | 
 |     def __init__(self, value=1): | 
 |         Semaphore.__init__(self, value) | 
 |         self._initial_value = value | 
 |  | 
 |     def release(self): | 
 |         if self._value >= self._initial_value: | 
 |             raise ValueError("Semaphore released too many times") | 
 |         return Semaphore.release(self) | 
 |  | 
 |  | 
 | class Event: | 
 |  | 
 |     # After Tim Peters' event class (without is_posted()) | 
 |  | 
 |     def __init__(self): | 
 |         self._cond = Condition(Lock()) | 
 |         self._flag = False | 
 |  | 
 |     def _reset_internal_locks(self): | 
 |         # private!  called by Thread._reset_internal_locks by _after_fork() | 
 |         self._cond.__init__() | 
 |  | 
 |     def is_set(self): | 
 |         return self._flag | 
 |  | 
 |     isSet = is_set | 
 |  | 
 |     def set(self): | 
 |         self._cond.acquire() | 
 |         try: | 
 |             self._flag = True | 
 |             self._cond.notify_all() | 
 |         finally: | 
 |             self._cond.release() | 
 |  | 
 |     def clear(self): | 
 |         self._cond.acquire() | 
 |         try: | 
 |             self._flag = False | 
 |         finally: | 
 |             self._cond.release() | 
 |  | 
 |     def wait(self, timeout=None): | 
 |         self._cond.acquire() | 
 |         try: | 
 |             signaled = self._flag | 
 |             if not signaled: | 
 |                 signaled = self._cond.wait(timeout) | 
 |             return signaled | 
 |         finally: | 
 |             self._cond.release() | 
 |  | 
 |  | 
 | # A barrier class.  Inspired in part by the pthread_barrier_* api and | 
 | # the CyclicBarrier class from Java.  See | 
 | # http://sourceware.org/pthreads-win32/manual/pthread_barrier_init.html and | 
 | # http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/ | 
 | #        CyclicBarrier.html | 
 | # for information. | 
 | # We maintain two main states, 'filling' and 'draining' enabling the barrier | 
 | # to be cyclic.  Threads are not allowed into it until it has fully drained | 
 | # since the previous cycle.  In addition, a 'resetting' state exists which is | 
 | # similar to 'draining' except that threads leave with a BrokenBarrierError, | 
 | # and a 'broken' state in which all threads get the exception. | 
 | class Barrier: | 
 |     """ | 
 |     Barrier.  Useful for synchronizing a fixed number of threads | 
 |     at known synchronization points.  Threads block on 'wait()' and are | 
 |     simultaneously once they have all made that call. | 
 |     """ | 
 |     def __init__(self, parties, action=None, timeout=None): | 
 |         """ | 
 |         Create a barrier, initialised to 'parties' threads. | 
 |         'action' is a callable which, when supplied, will be called | 
 |         by one of the threads after they have all entered the | 
 |         barrier and just prior to releasing them all. | 
 |         If a 'timeout' is provided, it is uses as the default for | 
 |         all subsequent 'wait()' calls. | 
 |         """ | 
 |         self._cond = Condition(Lock()) | 
 |         self._action = action | 
 |         self._timeout = timeout | 
 |         self._parties = parties | 
 |         self._state = 0 #0 filling, 1, draining, -1 resetting, -2 broken | 
 |         self._count = 0 | 
 |  | 
 |     def wait(self, timeout=None): | 
 |         """ | 
 |         Wait for the barrier.  When the specified number of threads have | 
 |         started waiting, they are all simultaneously awoken. If an 'action' | 
 |         was provided for the barrier, one of the threads will have executed | 
 |         that callback prior to returning. | 
 |         Returns an individual index number from 0 to 'parties-1'. | 
 |         """ | 
 |         if timeout is None: | 
 |             timeout = self._timeout | 
 |         with self._cond: | 
 |             self._enter() # Block while the barrier drains. | 
 |             index = self._count | 
 |             self._count += 1 | 
 |             try: | 
 |                 if index + 1 == self._parties: | 
 |                     # We release the barrier | 
 |                     self._release() | 
 |                 else: | 
 |                     # We wait until someone releases us | 
 |                     self._wait(timeout) | 
 |                 return index | 
 |             finally: | 
 |                 self._count -= 1 | 
 |                 # Wake up any threads waiting for barrier to drain. | 
 |                 self._exit() | 
 |  | 
 |     # Block until the barrier is ready for us, or raise an exception | 
 |     # if it is broken. | 
 |     def _enter(self): | 
 |         while self._state in (-1, 1): | 
 |             # It is draining or resetting, wait until done | 
 |             self._cond.wait() | 
 |         #see if the barrier is in a broken state | 
 |         if self._state < 0: | 
 |             raise BrokenBarrierError | 
 |         assert self._state == 0 | 
 |  | 
 |     # Optionally run the 'action' and release the threads waiting | 
 |     # in the barrier. | 
 |     def _release(self): | 
 |         try: | 
 |             if self._action: | 
 |                 self._action() | 
 |             # enter draining state | 
 |             self._state = 1 | 
 |             self._cond.notify_all() | 
 |         except: | 
 |             #an exception during the _action handler.  Break and reraise | 
 |             self._break() | 
 |             raise | 
 |  | 
 |     # Wait in the barrier until we are relased.  Raise an exception | 
 |     # if the barrier is reset or broken. | 
 |     def _wait(self, timeout): | 
 |         if not self._cond.wait_for(lambda : self._state != 0, timeout): | 
 |             #timed out.  Break the barrier | 
 |             self._break() | 
 |             raise BrokenBarrierError | 
 |         if self._state < 0: | 
 |             raise BrokenBarrierError | 
 |         assert self._state == 1 | 
 |  | 
 |     # If we are the last thread to exit the barrier, signal any threads | 
 |     # waiting for the barrier to drain. | 
 |     def _exit(self): | 
 |         if self._count == 0: | 
 |             if self._state in (-1, 1): | 
 |                 #resetting or draining | 
 |                 self._state = 0 | 
 |                 self._cond.notify_all() | 
 |  | 
 |     def reset(self): | 
 |         """ | 
 |         Reset the barrier to the initial state. | 
 |         Any threads currently waiting will get the BrokenBarrier exception | 
 |         raised. | 
 |         """ | 
 |         with self._cond: | 
 |             if self._count > 0: | 
 |                 if self._state == 0: | 
 |                     #reset the barrier, waking up threads | 
 |                     self._state = -1 | 
 |                 elif self._state == -2: | 
 |                     #was broken, set it to reset state | 
 |                     #which clears when the last thread exits | 
 |                     self._state = -1 | 
 |             else: | 
 |                 self._state = 0 | 
 |             self._cond.notify_all() | 
 |  | 
 |     def abort(self): | 
 |         """ | 
 |         Place the barrier into a 'broken' state. | 
 |         Useful in case of error.  Any currently waiting threads and | 
 |         threads attempting to 'wait()' will have BrokenBarrierError | 
 |         raised. | 
 |         """ | 
 |         with self._cond: | 
 |             self._break() | 
 |  | 
 |     def _break(self): | 
 |         # An internal error was detected.  The barrier is set to | 
 |         # a broken state all parties awakened. | 
 |         self._state = -2 | 
 |         self._cond.notify_all() | 
 |  | 
 |     @property | 
 |     def parties(self): | 
 |         """ | 
 |         Return the number of threads required to trip the barrier. | 
 |         """ | 
 |         return self._parties | 
 |  | 
 |     @property | 
 |     def n_waiting(self): | 
 |         """ | 
 |         Return the number of threads that are currently waiting at the barrier. | 
 |         """ | 
 |         # We don't need synchronization here since this is an ephemeral result | 
 |         # anyway.  It returns the correct value in the steady state. | 
 |         if self._state == 0: | 
 |             return self._count | 
 |         return 0 | 
 |  | 
 |     @property | 
 |     def broken(self): | 
 |         """ | 
 |         Return True if the barrier is in a broken state | 
 |         """ | 
 |         return self._state == -2 | 
 |  | 
 | #exception raised by the Barrier class | 
 | class BrokenBarrierError(RuntimeError): pass | 
 |  | 
 |  | 
 | # Helper to generate new thread names | 
 | _counter = 0 | 
 | def _newname(template="Thread-%d"): | 
 |     global _counter | 
 |     _counter = _counter + 1 | 
 |     return template % _counter | 
 |  | 
 | # Active thread administration | 
 | _active_limbo_lock = _allocate_lock() | 
 | _active = {}    # maps thread id to Thread object | 
 | _limbo = {} | 
 |  | 
 | # For debug and leak testing | 
 | _dangling = WeakSet() | 
 |  | 
 | # Main class for threads | 
 |  | 
 | class Thread: | 
 |  | 
 |     __initialized = False | 
 |     # Need to store a reference to sys.exc_info for printing | 
 |     # out exceptions when a thread tries to use a global var. during interp. | 
 |     # shutdown and thus raises an exception about trying to perform some | 
 |     # operation on/with a NoneType | 
 |     __exc_info = _sys.exc_info | 
 |     # Keep sys.exc_clear too to clear the exception just before | 
 |     # allowing .join() to return. | 
 |     #XXX __exc_clear = _sys.exc_clear | 
 |  | 
 |     def __init__(self, group=None, target=None, name=None, | 
 |                  args=(), kwargs=None, *, daemon=None): | 
 |         assert group is None, "group argument must be None for now" | 
 |         if kwargs is None: | 
 |             kwargs = {} | 
 |         self._target = target | 
 |         self._name = str(name or _newname()) | 
 |         self._args = args | 
 |         self._kwargs = kwargs | 
 |         if daemon is not None: | 
 |             self._daemonic = daemon | 
 |         else: | 
 |             self._daemonic = current_thread().daemon | 
 |         self._ident = None | 
 |         self._started = Event() | 
 |         self._stopped = False | 
 |         self._block = Condition(Lock()) | 
 |         self._initialized = True | 
 |         # sys.stderr is not stored in the class like | 
 |         # sys.exc_info since it can be changed between instances | 
 |         self._stderr = _sys.stderr | 
 |         _dangling.add(self) | 
 |  | 
 |     def _reset_internal_locks(self): | 
 |         # private!  Called by _after_fork() to reset our internal locks as | 
 |         # they may be in an invalid state leading to a deadlock or crash. | 
 |         if hasattr(self, '_block'):  # DummyThread deletes _block | 
 |             self._block.__init__() | 
 |         self._started._reset_internal_locks() | 
 |  | 
 |     def __repr__(self): | 
 |         assert self._initialized, "Thread.__init__() was not called" | 
 |         status = "initial" | 
 |         if self._started.is_set(): | 
 |             status = "started" | 
 |         if self._stopped: | 
 |             status = "stopped" | 
 |         if self._daemonic: | 
 |             status += " daemon" | 
 |         if self._ident is not None: | 
 |             status += " %s" % self._ident | 
 |         return "<%s(%s, %s)>" % (self.__class__.__name__, self._name, status) | 
 |  | 
 |     def start(self): | 
 |         if not self._initialized: | 
 |             raise RuntimeError("thread.__init__() not called") | 
 |  | 
 |         if self._started.is_set(): | 
 |             raise RuntimeError("threads can only be started once") | 
 |         with _active_limbo_lock: | 
 |             _limbo[self] = self | 
 |         try: | 
 |             _start_new_thread(self._bootstrap, ()) | 
 |         except Exception: | 
 |             with _active_limbo_lock: | 
 |                 del _limbo[self] | 
 |             raise | 
 |         self._started.wait() | 
 |  | 
 |     def run(self): | 
 |         try: | 
 |             if self._target: | 
 |                 self._target(*self._args, **self._kwargs) | 
 |         finally: | 
 |             # Avoid a refcycle if the thread is running a function with | 
 |             # an argument that has a member that points to the thread. | 
 |             del self._target, self._args, self._kwargs | 
 |  | 
 |     def _bootstrap(self): | 
 |         # Wrapper around the real bootstrap code that ignores | 
 |         # exceptions during interpreter cleanup.  Those typically | 
 |         # happen when a daemon thread wakes up at an unfortunate | 
 |         # moment, finds the world around it destroyed, and raises some | 
 |         # random exception *** while trying to report the exception in | 
 |         # _bootstrap_inner() below ***.  Those random exceptions | 
 |         # don't help anybody, and they confuse users, so we suppress | 
 |         # them.  We suppress them only when it appears that the world | 
 |         # indeed has already been destroyed, so that exceptions in | 
 |         # _bootstrap_inner() during normal business hours are properly | 
 |         # reported.  Also, we only suppress them for daemonic threads; | 
 |         # if a non-daemonic encounters this, something else is wrong. | 
 |         try: | 
 |             self._bootstrap_inner() | 
 |         except: | 
 |             if self._daemonic and _sys is None: | 
 |                 return | 
 |             raise | 
 |  | 
 |     def _set_ident(self): | 
 |         self._ident = get_ident() | 
 |  | 
 |     def _bootstrap_inner(self): | 
 |         try: | 
 |             self._set_ident() | 
 |             self._started.set() | 
 |             with _active_limbo_lock: | 
 |                 _active[self._ident] = self | 
 |                 del _limbo[self] | 
 |  | 
 |             if _trace_hook: | 
 |                 _sys.settrace(_trace_hook) | 
 |             if _profile_hook: | 
 |                 _sys.setprofile(_profile_hook) | 
 |  | 
 |             try: | 
 |                 self.run() | 
 |             except SystemExit: | 
 |                 pass | 
 |             except: | 
 |                 # If sys.stderr is no more (most likely from interpreter | 
 |                 # shutdown) use self._stderr.  Otherwise still use sys (as in | 
 |                 # _sys) in case sys.stderr was redefined since the creation of | 
 |                 # self. | 
 |                 if _sys: | 
 |                     _sys.stderr.write("Exception in thread %s:\n%s\n" % | 
 |                                       (self.name, _format_exc())) | 
 |                 else: | 
 |                     # Do the best job possible w/o a huge amt. of code to | 
 |                     # approximate a traceback (code ideas from | 
 |                     # Lib/traceback.py) | 
 |                     exc_type, exc_value, exc_tb = self._exc_info() | 
 |                     try: | 
 |                         print(( | 
 |                             "Exception in thread " + self.name + | 
 |                             " (most likely raised during interpreter shutdown):"), file=self._stderr) | 
 |                         print(( | 
 |                             "Traceback (most recent call last):"), file=self._stderr) | 
 |                         while exc_tb: | 
 |                             print(( | 
 |                                 '  File "%s", line %s, in %s' % | 
 |                                 (exc_tb.tb_frame.f_code.co_filename, | 
 |                                     exc_tb.tb_lineno, | 
 |                                     exc_tb.tb_frame.f_code.co_name)), file=self._stderr) | 
 |                             exc_tb = exc_tb.tb_next | 
 |                         print(("%s: %s" % (exc_type, exc_value)), file=self._stderr) | 
 |                     # Make sure that exc_tb gets deleted since it is a memory | 
 |                     # hog; deleting everything else is just for thoroughness | 
 |                     finally: | 
 |                         del exc_type, exc_value, exc_tb | 
 |             finally: | 
 |                 # Prevent a race in | 
 |                 # test_threading.test_no_refcycle_through_target when | 
 |                 # the exception keeps the target alive past when we | 
 |                 # assert that it's dead. | 
 |                 #XXX self.__exc_clear() | 
 |                 pass | 
 |         finally: | 
 |             with _active_limbo_lock: | 
 |                 self._stop() | 
 |                 try: | 
 |                     # We don't call self._delete() because it also | 
 |                     # grabs _active_limbo_lock. | 
 |                     del _active[get_ident()] | 
 |                 except: | 
 |                     pass | 
 |  | 
 |     def _stop(self): | 
 |         self._block.acquire() | 
 |         self._stopped = True | 
 |         self._block.notify_all() | 
 |         self._block.release() | 
 |  | 
 |     def _delete(self): | 
 |         "Remove current thread from the dict of currently running threads." | 
 |  | 
 |         # Notes about running with _dummy_thread: | 
 |         # | 
 |         # Must take care to not raise an exception if _dummy_thread is being | 
 |         # used (and thus this module is being used as an instance of | 
 |         # dummy_threading).  _dummy_thread.get_ident() always returns -1 since | 
 |         # there is only one thread if _dummy_thread is being used.  Thus | 
 |         # len(_active) is always <= 1 here, and any Thread instance created | 
 |         # overwrites the (if any) thread currently registered in _active. | 
 |         # | 
 |         # An instance of _MainThread is always created by 'threading'.  This | 
 |         # gets overwritten the instant an instance of Thread is created; both | 
 |         # threads return -1 from _dummy_thread.get_ident() and thus have the | 
 |         # same key in the dict.  So when the _MainThread instance created by | 
 |         # 'threading' tries to clean itself up when atexit calls this method | 
 |         # it gets a KeyError if another Thread instance was created. | 
 |         # | 
 |         # This all means that KeyError from trying to delete something from | 
 |         # _active if dummy_threading is being used is a red herring.  But | 
 |         # since it isn't if dummy_threading is *not* being used then don't | 
 |         # hide the exception. | 
 |  | 
 |         try: | 
 |             with _active_limbo_lock: | 
 |                 del _active[get_ident()] | 
 |                 # There must not be any python code between the previous line | 
 |                 # and after the lock is released.  Otherwise a tracing function | 
 |                 # could try to acquire the lock again in the same thread, (in | 
 |                 # current_thread()), and would block. | 
 |         except KeyError: | 
 |             if 'dummy_threading' not in _sys.modules: | 
 |                 raise | 
 |  | 
 |     def join(self, timeout=None): | 
 |         if not self._initialized: | 
 |             raise RuntimeError("Thread.__init__() not called") | 
 |         if not self._started.is_set(): | 
 |             raise RuntimeError("cannot join thread before it is started") | 
 |         if self is current_thread(): | 
 |             raise RuntimeError("cannot join current thread") | 
 |  | 
 |         self._block.acquire() | 
 |         try: | 
 |             if timeout is None: | 
 |                 while not self._stopped: | 
 |                     self._block.wait() | 
 |             else: | 
 |                 deadline = _time() + timeout | 
 |                 while not self._stopped: | 
 |                     delay = deadline - _time() | 
 |                     if delay <= 0: | 
 |                         break | 
 |                     self._block.wait(delay) | 
 |         finally: | 
 |             self._block.release() | 
 |  | 
 |     @property | 
 |     def name(self): | 
 |         assert self._initialized, "Thread.__init__() not called" | 
 |         return self._name | 
 |  | 
 |     @name.setter | 
 |     def name(self, name): | 
 |         assert self._initialized, "Thread.__init__() not called" | 
 |         self._name = str(name) | 
 |  | 
 |     @property | 
 |     def ident(self): | 
 |         assert self._initialized, "Thread.__init__() not called" | 
 |         return self._ident | 
 |  | 
 |     def is_alive(self): | 
 |         assert self._initialized, "Thread.__init__() not called" | 
 |         return self._started.is_set() and not self._stopped | 
 |  | 
 |     isAlive = is_alive | 
 |  | 
 |     @property | 
 |     def daemon(self): | 
 |         assert self._initialized, "Thread.__init__() not called" | 
 |         return self._daemonic | 
 |  | 
 |     @daemon.setter | 
 |     def daemon(self, daemonic): | 
 |         if not self._initialized: | 
 |             raise RuntimeError("Thread.__init__() not called") | 
 |         if self._started.is_set(): | 
 |             raise RuntimeError("cannot set daemon status of active thread"); | 
 |         self._daemonic = daemonic | 
 |  | 
 |     def isDaemon(self): | 
 |         return self.daemon | 
 |  | 
 |     def setDaemon(self, daemonic): | 
 |         self.daemon = daemonic | 
 |  | 
 |     def getName(self): | 
 |         return self.name | 
 |  | 
 |     def setName(self, name): | 
 |         self.name = name | 
 |  | 
 | # The timer class was contributed by Itamar Shtull-Trauring | 
 |  | 
 | class Timer(Thread): | 
 |     """Call a function after a specified number of seconds: | 
 |  | 
 |     t = Timer(30.0, f, args=None, kwargs=None) | 
 |     t.start() | 
 |     t.cancel() # stop the timer's action if it's still waiting | 
 |     """ | 
 |  | 
 |     def __init__(self, interval, function, args=None, kwargs=None): | 
 |         Thread.__init__(self) | 
 |         self.interval = interval | 
 |         self.function = function | 
 |         self.args = args if args is not None else [] | 
 |         self.kwargs = kwargs if kwargs is not None else {} | 
 |         self.finished = Event() | 
 |  | 
 |     def cancel(self): | 
 |         """Stop the timer if it hasn't finished yet""" | 
 |         self.finished.set() | 
 |  | 
 |     def run(self): | 
 |         self.finished.wait(self.interval) | 
 |         if not self.finished.is_set(): | 
 |             self.function(*self.args, **self.kwargs) | 
 |         self.finished.set() | 
 |  | 
 | # Special thread class to represent the main thread | 
 | # This is garbage collected through an exit handler | 
 |  | 
 | class _MainThread(Thread): | 
 |  | 
 |     def __init__(self): | 
 |         Thread.__init__(self, name="MainThread", daemon=False) | 
 |         self._started.set() | 
 |         self._set_ident() | 
 |         with _active_limbo_lock: | 
 |             _active[self._ident] = self | 
 |  | 
 |     def _exitfunc(self): | 
 |         self._stop() | 
 |         t = _pickSomeNonDaemonThread() | 
 |         while t: | 
 |             t.join() | 
 |             t = _pickSomeNonDaemonThread() | 
 |         self._delete() | 
 |  | 
 | def _pickSomeNonDaemonThread(): | 
 |     for t in enumerate(): | 
 |         if not t.daemon and t.is_alive(): | 
 |             return t | 
 |     return None | 
 |  | 
 |  | 
 | # Dummy thread class to represent threads not started here. | 
 | # These aren't garbage collected when they die, nor can they be waited for. | 
 | # If they invoke anything in threading.py that calls current_thread(), they | 
 | # leave an entry in the _active dict forever after. | 
 | # Their purpose is to return *something* from current_thread(). | 
 | # They are marked as daemon threads so we won't wait for them | 
 | # when we exit (conform previous semantics). | 
 |  | 
 | class _DummyThread(Thread): | 
 |  | 
 |     def __init__(self): | 
 |         Thread.__init__(self, name=_newname("Dummy-%d"), daemon=True) | 
 |  | 
 |         # Thread._block consumes an OS-level locking primitive, which | 
 |         # can never be used by a _DummyThread.  Since a _DummyThread | 
 |         # instance is immortal, that's bad, so release this resource. | 
 |         del self._block | 
 |  | 
 |         self._started.set() | 
 |         self._set_ident() | 
 |         with _active_limbo_lock: | 
 |             _active[self._ident] = self | 
 |  | 
 |     def _stop(self): | 
 |         pass | 
 |  | 
 |     def join(self, timeout=None): | 
 |         assert False, "cannot join a dummy thread" | 
 |  | 
 |  | 
 | # Global API functions | 
 |  | 
 | def current_thread(): | 
 |     try: | 
 |         return _active[get_ident()] | 
 |     except KeyError: | 
 |         return _DummyThread() | 
 |  | 
 | currentThread = current_thread | 
 |  | 
 | def active_count(): | 
 |     with _active_limbo_lock: | 
 |         return len(_active) + len(_limbo) | 
 |  | 
 | activeCount = active_count | 
 |  | 
 | def _enumerate(): | 
 |     # Same as enumerate(), but without the lock. Internal use only. | 
 |     return list(_active.values()) + list(_limbo.values()) | 
 |  | 
 | def enumerate(): | 
 |     with _active_limbo_lock: | 
 |         return list(_active.values()) + list(_limbo.values()) | 
 |  | 
 | from _thread import stack_size | 
 |  | 
 | # Create the main thread object, | 
 | # and make it available for the interpreter | 
 | # (Py_Main) as threading._shutdown. | 
 |  | 
 | _shutdown = _MainThread()._exitfunc | 
 |  | 
 | # get thread-local implementation, either from the thread | 
 | # module, or from the python fallback | 
 |  | 
 | try: | 
 |     from _thread import _local as local | 
 | except ImportError: | 
 |     from _threading_local import local | 
 |  | 
 |  | 
 | def _after_fork(): | 
 |     # This function is called by Python/ceval.c:PyEval_ReInitThreads which | 
 |     # is called from PyOS_AfterFork.  Here we cleanup threading module state | 
 |     # that should not exist after a fork. | 
 |  | 
 |     # Reset _active_limbo_lock, in case we forked while the lock was held | 
 |     # by another (non-forked) thread.  http://bugs.python.org/issue874900 | 
 |     global _active_limbo_lock | 
 |     _active_limbo_lock = _allocate_lock() | 
 |  | 
 |     # fork() only copied the current thread; clear references to others. | 
 |     new_active = {} | 
 |     current = current_thread() | 
 |     with _active_limbo_lock: | 
 |         for thread in _enumerate(): | 
 |             # Any lock/condition variable may be currently locked or in an | 
 |             # invalid state, so we reinitialize them. | 
 |             thread._reset_internal_locks() | 
 |             if thread is current: | 
 |                 # There is only one active thread. We reset the ident to | 
 |                 # its new value since it can have changed. | 
 |                 ident = get_ident() | 
 |                 thread._ident = ident | 
 |                 new_active[ident] = thread | 
 |             else: | 
 |                 # All the others are already stopped. | 
 |                 thread._stop() | 
 |  | 
 |         _limbo.clear() | 
 |         _active.clear() | 
 |         _active.update(new_active) | 
 |         assert len(_active) == 1 |