xref: /third_party/python/Lib/threading.py (revision 7db96d56)
17db96d56Sopenharmony_ci"""Thread module emulating a subset of Java's threading model."""
27db96d56Sopenharmony_ci
37db96d56Sopenharmony_ciimport os as _os
47db96d56Sopenharmony_ciimport sys as _sys
57db96d56Sopenharmony_ciimport _thread
67db96d56Sopenharmony_ciimport functools
77db96d56Sopenharmony_ci
87db96d56Sopenharmony_cifrom time import monotonic as _time
97db96d56Sopenharmony_cifrom _weakrefset import WeakSet
107db96d56Sopenharmony_cifrom itertools import islice as _islice, count as _count
117db96d56Sopenharmony_citry:
127db96d56Sopenharmony_ci    from _collections import deque as _deque
137db96d56Sopenharmony_ciexcept ImportError:
147db96d56Sopenharmony_ci    from collections import deque as _deque
157db96d56Sopenharmony_ci
167db96d56Sopenharmony_ci# Note regarding PEP 8 compliant names
177db96d56Sopenharmony_ci#  This threading model was originally inspired by Java, and inherited
187db96d56Sopenharmony_ci# the convention of camelCase function and method names from that
197db96d56Sopenharmony_ci# language. Those original names are not in any imminent danger of
207db96d56Sopenharmony_ci# being deprecated (even for Py3k),so this module provides them as an
217db96d56Sopenharmony_ci# alias for the PEP 8 compliant names
227db96d56Sopenharmony_ci# Note that using the new PEP 8 compliant names facilitates substitution
237db96d56Sopenharmony_ci# with the multiprocessing module, which doesn't provide the old
247db96d56Sopenharmony_ci# Java inspired names.
257db96d56Sopenharmony_ci
267db96d56Sopenharmony_ci__all__ = ['get_ident', 'active_count', 'Condition', 'current_thread',
277db96d56Sopenharmony_ci           'enumerate', 'main_thread', 'TIMEOUT_MAX',
287db96d56Sopenharmony_ci           'Event', 'Lock', 'RLock', 'Semaphore', 'BoundedSemaphore', 'Thread',
297db96d56Sopenharmony_ci           'Barrier', 'BrokenBarrierError', 'Timer', 'ThreadError',
307db96d56Sopenharmony_ci           'setprofile', 'settrace', 'local', 'stack_size',
317db96d56Sopenharmony_ci           'excepthook', 'ExceptHookArgs', 'gettrace', 'getprofile']
327db96d56Sopenharmony_ci
337db96d56Sopenharmony_ci# Rename some stuff so "from threading import *" is safe
347db96d56Sopenharmony_ci_start_new_thread = _thread.start_new_thread
357db96d56Sopenharmony_ci_allocate_lock = _thread.allocate_lock
367db96d56Sopenharmony_ci_set_sentinel = _thread._set_sentinel
377db96d56Sopenharmony_ciget_ident = _thread.get_ident
387db96d56Sopenharmony_citry:
397db96d56Sopenharmony_ci    get_native_id = _thread.get_native_id
407db96d56Sopenharmony_ci    _HAVE_THREAD_NATIVE_ID = True
417db96d56Sopenharmony_ci    __all__.append('get_native_id')
427db96d56Sopenharmony_ciexcept AttributeError:
437db96d56Sopenharmony_ci    _HAVE_THREAD_NATIVE_ID = False
447db96d56Sopenharmony_ciThreadError = _thread.error
457db96d56Sopenharmony_citry:
467db96d56Sopenharmony_ci    _CRLock = _thread.RLock
477db96d56Sopenharmony_ciexcept AttributeError:
487db96d56Sopenharmony_ci    _CRLock = None
497db96d56Sopenharmony_ciTIMEOUT_MAX = _thread.TIMEOUT_MAX
507db96d56Sopenharmony_cidel _thread
517db96d56Sopenharmony_ci
527db96d56Sopenharmony_ci
537db96d56Sopenharmony_ci# Support for profile and trace hooks
547db96d56Sopenharmony_ci
557db96d56Sopenharmony_ci_profile_hook = None
567db96d56Sopenharmony_ci_trace_hook = None
577db96d56Sopenharmony_ci
587db96d56Sopenharmony_cidef setprofile(func):
597db96d56Sopenharmony_ci    """Set a profile function for all threads started from the threading module.
607db96d56Sopenharmony_ci
617db96d56Sopenharmony_ci    The func will be passed to sys.setprofile() for each thread, before its
627db96d56Sopenharmony_ci    run() method is called.
637db96d56Sopenharmony_ci
647db96d56Sopenharmony_ci    """
657db96d56Sopenharmony_ci    global _profile_hook
667db96d56Sopenharmony_ci    _profile_hook = func
677db96d56Sopenharmony_ci
687db96d56Sopenharmony_cidef getprofile():
697db96d56Sopenharmony_ci    """Get the profiler function as set by threading.setprofile()."""
707db96d56Sopenharmony_ci    return _profile_hook
717db96d56Sopenharmony_ci
727db96d56Sopenharmony_cidef settrace(func):
737db96d56Sopenharmony_ci    """Set a trace function for all threads started from the threading module.
747db96d56Sopenharmony_ci
757db96d56Sopenharmony_ci    The func will be passed to sys.settrace() for each thread, before its run()
767db96d56Sopenharmony_ci    method is called.
777db96d56Sopenharmony_ci
787db96d56Sopenharmony_ci    """
797db96d56Sopenharmony_ci    global _trace_hook
807db96d56Sopenharmony_ci    _trace_hook = func
817db96d56Sopenharmony_ci
827db96d56Sopenharmony_cidef gettrace():
837db96d56Sopenharmony_ci    """Get the trace function as set by threading.settrace()."""
847db96d56Sopenharmony_ci    return _trace_hook
857db96d56Sopenharmony_ci
867db96d56Sopenharmony_ci# Synchronization classes
877db96d56Sopenharmony_ci
887db96d56Sopenharmony_ciLock = _allocate_lock
897db96d56Sopenharmony_ci
907db96d56Sopenharmony_cidef RLock(*args, **kwargs):
917db96d56Sopenharmony_ci    """Factory function that returns a new reentrant lock.
927db96d56Sopenharmony_ci
937db96d56Sopenharmony_ci    A reentrant lock must be released by the thread that acquired it. Once a
947db96d56Sopenharmony_ci    thread has acquired a reentrant lock, the same thread may acquire it again
957db96d56Sopenharmony_ci    without blocking; the thread must release it once for each time it has
967db96d56Sopenharmony_ci    acquired it.
977db96d56Sopenharmony_ci
987db96d56Sopenharmony_ci    """
997db96d56Sopenharmony_ci    if _CRLock is None:
1007db96d56Sopenharmony_ci        return _PyRLock(*args, **kwargs)
1017db96d56Sopenharmony_ci    return _CRLock(*args, **kwargs)
1027db96d56Sopenharmony_ci
1037db96d56Sopenharmony_ciclass _RLock:
1047db96d56Sopenharmony_ci    """This class implements reentrant lock objects.
1057db96d56Sopenharmony_ci
1067db96d56Sopenharmony_ci    A reentrant lock must be released by the thread that acquired it. Once a
1077db96d56Sopenharmony_ci    thread has acquired a reentrant lock, the same thread may acquire it
1087db96d56Sopenharmony_ci    again without blocking; the thread must release it once for each time it
1097db96d56Sopenharmony_ci    has acquired it.
1107db96d56Sopenharmony_ci
1117db96d56Sopenharmony_ci    """
1127db96d56Sopenharmony_ci
1137db96d56Sopenharmony_ci    def __init__(self):
1147db96d56Sopenharmony_ci        self._block = _allocate_lock()
1157db96d56Sopenharmony_ci        self._owner = None
1167db96d56Sopenharmony_ci        self._count = 0
1177db96d56Sopenharmony_ci
1187db96d56Sopenharmony_ci    def __repr__(self):
1197db96d56Sopenharmony_ci        owner = self._owner
1207db96d56Sopenharmony_ci        try:
1217db96d56Sopenharmony_ci            owner = _active[owner].name
1227db96d56Sopenharmony_ci        except KeyError:
1237db96d56Sopenharmony_ci            pass
1247db96d56Sopenharmony_ci        return "<%s %s.%s object owner=%r count=%d at %s>" % (
1257db96d56Sopenharmony_ci            "locked" if self._block.locked() else "unlocked",
1267db96d56Sopenharmony_ci            self.__class__.__module__,
1277db96d56Sopenharmony_ci            self.__class__.__qualname__,
1287db96d56Sopenharmony_ci            owner,
1297db96d56Sopenharmony_ci            self._count,
1307db96d56Sopenharmony_ci            hex(id(self))
1317db96d56Sopenharmony_ci        )
1327db96d56Sopenharmony_ci
1337db96d56Sopenharmony_ci    def _at_fork_reinit(self):
1347db96d56Sopenharmony_ci        self._block._at_fork_reinit()
1357db96d56Sopenharmony_ci        self._owner = None
1367db96d56Sopenharmony_ci        self._count = 0
1377db96d56Sopenharmony_ci
1387db96d56Sopenharmony_ci    def acquire(self, blocking=True, timeout=-1):
1397db96d56Sopenharmony_ci        """Acquire a lock, blocking or non-blocking.
1407db96d56Sopenharmony_ci
1417db96d56Sopenharmony_ci        When invoked without arguments: if this thread already owns the lock,
1427db96d56Sopenharmony_ci        increment the recursion level by one, and return immediately. Otherwise,
1437db96d56Sopenharmony_ci        if another thread owns the lock, block until the lock is unlocked. Once
1447db96d56Sopenharmony_ci        the lock is unlocked (not owned by any thread), then grab ownership, set
1457db96d56Sopenharmony_ci        the recursion level to one, and return. If more than one thread is
1467db96d56Sopenharmony_ci        blocked waiting until the lock is unlocked, only one at a time will be
1477db96d56Sopenharmony_ci        able to grab ownership of the lock. There is no return value in this
1487db96d56Sopenharmony_ci        case.
1497db96d56Sopenharmony_ci
1507db96d56Sopenharmony_ci        When invoked with the blocking argument set to true, do the same thing
1517db96d56Sopenharmony_ci        as when called without arguments, and return true.
1527db96d56Sopenharmony_ci
1537db96d56Sopenharmony_ci        When invoked with the blocking argument set to false, do not block. If a
1547db96d56Sopenharmony_ci        call without an argument would block, return false immediately;
1557db96d56Sopenharmony_ci        otherwise, do the same thing as when called without arguments, and
1567db96d56Sopenharmony_ci        return true.
1577db96d56Sopenharmony_ci
1587db96d56Sopenharmony_ci        When invoked with the floating-point timeout argument set to a positive
1597db96d56Sopenharmony_ci        value, block for at most the number of seconds specified by timeout
1607db96d56Sopenharmony_ci        and as long as the lock cannot be acquired.  Return true if the lock has
1617db96d56Sopenharmony_ci        been acquired, false if the timeout has elapsed.
1627db96d56Sopenharmony_ci
1637db96d56Sopenharmony_ci        """
1647db96d56Sopenharmony_ci        me = get_ident()
1657db96d56Sopenharmony_ci        if self._owner == me:
1667db96d56Sopenharmony_ci            self._count += 1
1677db96d56Sopenharmony_ci            return 1
1687db96d56Sopenharmony_ci        rc = self._block.acquire(blocking, timeout)
1697db96d56Sopenharmony_ci        if rc:
1707db96d56Sopenharmony_ci            self._owner = me
1717db96d56Sopenharmony_ci            self._count = 1
1727db96d56Sopenharmony_ci        return rc
1737db96d56Sopenharmony_ci
1747db96d56Sopenharmony_ci    __enter__ = acquire
1757db96d56Sopenharmony_ci
1767db96d56Sopenharmony_ci    def release(self):
1777db96d56Sopenharmony_ci        """Release a lock, decrementing the recursion level.
1787db96d56Sopenharmony_ci
1797db96d56Sopenharmony_ci        If after the decrement it is zero, reset the lock to unlocked (not owned
1807db96d56Sopenharmony_ci        by any thread), and if any other threads are blocked waiting for the
1817db96d56Sopenharmony_ci        lock to become unlocked, allow exactly one of them to proceed. If after
1827db96d56Sopenharmony_ci        the decrement the recursion level is still nonzero, the lock remains
1837db96d56Sopenharmony_ci        locked and owned by the calling thread.
1847db96d56Sopenharmony_ci
1857db96d56Sopenharmony_ci        Only call this method when the calling thread owns the lock. A
1867db96d56Sopenharmony_ci        RuntimeError is raised if this method is called when the lock is
1877db96d56Sopenharmony_ci        unlocked.
1887db96d56Sopenharmony_ci
1897db96d56Sopenharmony_ci        There is no return value.
1907db96d56Sopenharmony_ci
1917db96d56Sopenharmony_ci        """
1927db96d56Sopenharmony_ci        if self._owner != get_ident():
1937db96d56Sopenharmony_ci            raise RuntimeError("cannot release un-acquired lock")
1947db96d56Sopenharmony_ci        self._count = count = self._count - 1
1957db96d56Sopenharmony_ci        if not count:
1967db96d56Sopenharmony_ci            self._owner = None
1977db96d56Sopenharmony_ci            self._block.release()
1987db96d56Sopenharmony_ci
1997db96d56Sopenharmony_ci    def __exit__(self, t, v, tb):
2007db96d56Sopenharmony_ci        self.release()
2017db96d56Sopenharmony_ci
2027db96d56Sopenharmony_ci    # Internal methods used by condition variables
2037db96d56Sopenharmony_ci
2047db96d56Sopenharmony_ci    def _acquire_restore(self, state):
2057db96d56Sopenharmony_ci        self._block.acquire()
2067db96d56Sopenharmony_ci        self._count, self._owner = state
2077db96d56Sopenharmony_ci
2087db96d56Sopenharmony_ci    def _release_save(self):
2097db96d56Sopenharmony_ci        if self._count == 0:
2107db96d56Sopenharmony_ci            raise RuntimeError("cannot release un-acquired lock")
2117db96d56Sopenharmony_ci        count = self._count
2127db96d56Sopenharmony_ci        self._count = 0
2137db96d56Sopenharmony_ci        owner = self._owner
2147db96d56Sopenharmony_ci        self._owner = None
2157db96d56Sopenharmony_ci        self._block.release()
2167db96d56Sopenharmony_ci        return (count, owner)
2177db96d56Sopenharmony_ci
2187db96d56Sopenharmony_ci    def _is_owned(self):
2197db96d56Sopenharmony_ci        return self._owner == get_ident()
2207db96d56Sopenharmony_ci
2217db96d56Sopenharmony_ci_PyRLock = _RLock
2227db96d56Sopenharmony_ci
2237db96d56Sopenharmony_ci
2247db96d56Sopenharmony_ciclass Condition:
2257db96d56Sopenharmony_ci    """Class that implements a condition variable.
2267db96d56Sopenharmony_ci
2277db96d56Sopenharmony_ci    A condition variable allows one or more threads to wait until they are
2287db96d56Sopenharmony_ci    notified by another thread.
2297db96d56Sopenharmony_ci
2307db96d56Sopenharmony_ci    If the lock argument is given and not None, it must be a Lock or RLock
2317db96d56Sopenharmony_ci    object, and it is used as the underlying lock. Otherwise, a new RLock object
2327db96d56Sopenharmony_ci    is created and used as the underlying lock.
2337db96d56Sopenharmony_ci
2347db96d56Sopenharmony_ci    """
2357db96d56Sopenharmony_ci
2367db96d56Sopenharmony_ci    def __init__(self, lock=None):
2377db96d56Sopenharmony_ci        if lock is None:
2387db96d56Sopenharmony_ci            lock = RLock()
2397db96d56Sopenharmony_ci        self._lock = lock
2407db96d56Sopenharmony_ci        # Export the lock's acquire() and release() methods
2417db96d56Sopenharmony_ci        self.acquire = lock.acquire
2427db96d56Sopenharmony_ci        self.release = lock.release
2437db96d56Sopenharmony_ci        # If the lock defines _release_save() and/or _acquire_restore(),
2447db96d56Sopenharmony_ci        # these override the default implementations (which just call
2457db96d56Sopenharmony_ci        # release() and acquire() on the lock).  Ditto for _is_owned().
2467db96d56Sopenharmony_ci        try:
2477db96d56Sopenharmony_ci            self._release_save = lock._release_save
2487db96d56Sopenharmony_ci        except AttributeError:
2497db96d56Sopenharmony_ci            pass
2507db96d56Sopenharmony_ci        try:
2517db96d56Sopenharmony_ci            self._acquire_restore = lock._acquire_restore
2527db96d56Sopenharmony_ci        except AttributeError:
2537db96d56Sopenharmony_ci            pass
2547db96d56Sopenharmony_ci        try:
2557db96d56Sopenharmony_ci            self._is_owned = lock._is_owned
2567db96d56Sopenharmony_ci        except AttributeError:
2577db96d56Sopenharmony_ci            pass
2587db96d56Sopenharmony_ci        self._waiters = _deque()
2597db96d56Sopenharmony_ci
2607db96d56Sopenharmony_ci    def _at_fork_reinit(self):
2617db96d56Sopenharmony_ci        self._lock._at_fork_reinit()
2627db96d56Sopenharmony_ci        self._waiters.clear()
2637db96d56Sopenharmony_ci
2647db96d56Sopenharmony_ci    def __enter__(self):
2657db96d56Sopenharmony_ci        return self._lock.__enter__()
2667db96d56Sopenharmony_ci
2677db96d56Sopenharmony_ci    def __exit__(self, *args):
2687db96d56Sopenharmony_ci        return self._lock.__exit__(*args)
2697db96d56Sopenharmony_ci
2707db96d56Sopenharmony_ci    def __repr__(self):
2717db96d56Sopenharmony_ci        return "<Condition(%s, %d)>" % (self._lock, len(self._waiters))
2727db96d56Sopenharmony_ci
2737db96d56Sopenharmony_ci    def _release_save(self):
2747db96d56Sopenharmony_ci        self._lock.release()           # No state to save
2757db96d56Sopenharmony_ci
2767db96d56Sopenharmony_ci    def _acquire_restore(self, x):
2777db96d56Sopenharmony_ci        self._lock.acquire()           # Ignore saved state
2787db96d56Sopenharmony_ci
2797db96d56Sopenharmony_ci    def _is_owned(self):
2807db96d56Sopenharmony_ci        # Return True if lock is owned by current_thread.
2817db96d56Sopenharmony_ci        # This method is called only if _lock doesn't have _is_owned().
2827db96d56Sopenharmony_ci        if self._lock.acquire(False):
2837db96d56Sopenharmony_ci            self._lock.release()
2847db96d56Sopenharmony_ci            return False
2857db96d56Sopenharmony_ci        else:
2867db96d56Sopenharmony_ci            return True
2877db96d56Sopenharmony_ci
2887db96d56Sopenharmony_ci    def wait(self, timeout=None):
2897db96d56Sopenharmony_ci        """Wait until notified or until a timeout occurs.
2907db96d56Sopenharmony_ci
2917db96d56Sopenharmony_ci        If the calling thread has not acquired the lock when this method is
2927db96d56Sopenharmony_ci        called, a RuntimeError is raised.
2937db96d56Sopenharmony_ci
2947db96d56Sopenharmony_ci        This method releases the underlying lock, and then blocks until it is
2957db96d56Sopenharmony_ci        awakened by a notify() or notify_all() call for the same condition
2967db96d56Sopenharmony_ci        variable in another thread, or until the optional timeout occurs. Once
2977db96d56Sopenharmony_ci        awakened or timed out, it re-acquires the lock and returns.
2987db96d56Sopenharmony_ci
2997db96d56Sopenharmony_ci        When the timeout argument is present and not None, it should be a
3007db96d56Sopenharmony_ci        floating point number specifying a timeout for the operation in seconds
3017db96d56Sopenharmony_ci        (or fractions thereof).
3027db96d56Sopenharmony_ci
3037db96d56Sopenharmony_ci        When the underlying lock is an RLock, it is not released using its
3047db96d56Sopenharmony_ci        release() method, since this may not actually unlock the lock when it
3057db96d56Sopenharmony_ci        was acquired multiple times recursively. Instead, an internal interface
3067db96d56Sopenharmony_ci        of the RLock class is used, which really unlocks it even when it has
3077db96d56Sopenharmony_ci        been recursively acquired several times. Another internal interface is
3087db96d56Sopenharmony_ci        then used to restore the recursion level when the lock is reacquired.
3097db96d56Sopenharmony_ci
3107db96d56Sopenharmony_ci        """
3117db96d56Sopenharmony_ci        if not self._is_owned():
3127db96d56Sopenharmony_ci            raise RuntimeError("cannot wait on un-acquired lock")
3137db96d56Sopenharmony_ci        waiter = _allocate_lock()
3147db96d56Sopenharmony_ci        waiter.acquire()
3157db96d56Sopenharmony_ci        self._waiters.append(waiter)
3167db96d56Sopenharmony_ci        saved_state = self._release_save()
3177db96d56Sopenharmony_ci        gotit = False
3187db96d56Sopenharmony_ci        try:    # restore state no matter what (e.g., KeyboardInterrupt)
3197db96d56Sopenharmony_ci            if timeout is None:
3207db96d56Sopenharmony_ci                waiter.acquire()
3217db96d56Sopenharmony_ci                gotit = True
3227db96d56Sopenharmony_ci            else:
3237db96d56Sopenharmony_ci                if timeout > 0:
3247db96d56Sopenharmony_ci                    gotit = waiter.acquire(True, timeout)
3257db96d56Sopenharmony_ci                else:
3267db96d56Sopenharmony_ci                    gotit = waiter.acquire(False)
3277db96d56Sopenharmony_ci            return gotit
3287db96d56Sopenharmony_ci        finally:
3297db96d56Sopenharmony_ci            self._acquire_restore(saved_state)
3307db96d56Sopenharmony_ci            if not gotit:
3317db96d56Sopenharmony_ci                try:
3327db96d56Sopenharmony_ci                    self._waiters.remove(waiter)
3337db96d56Sopenharmony_ci                except ValueError:
3347db96d56Sopenharmony_ci                    pass
3357db96d56Sopenharmony_ci
3367db96d56Sopenharmony_ci    def wait_for(self, predicate, timeout=None):
3377db96d56Sopenharmony_ci        """Wait until a condition evaluates to True.
3387db96d56Sopenharmony_ci
3397db96d56Sopenharmony_ci        predicate should be a callable which result will be interpreted as a
3407db96d56Sopenharmony_ci        boolean value.  A timeout may be provided giving the maximum time to
3417db96d56Sopenharmony_ci        wait.
3427db96d56Sopenharmony_ci
3437db96d56Sopenharmony_ci        """
3447db96d56Sopenharmony_ci        endtime = None
3457db96d56Sopenharmony_ci        waittime = timeout
3467db96d56Sopenharmony_ci        result = predicate()
3477db96d56Sopenharmony_ci        while not result:
3487db96d56Sopenharmony_ci            if waittime is not None:
3497db96d56Sopenharmony_ci                if endtime is None:
3507db96d56Sopenharmony_ci                    endtime = _time() + waittime
3517db96d56Sopenharmony_ci                else:
3527db96d56Sopenharmony_ci                    waittime = endtime - _time()
3537db96d56Sopenharmony_ci                    if waittime <= 0:
3547db96d56Sopenharmony_ci                        break
3557db96d56Sopenharmony_ci            self.wait(waittime)
3567db96d56Sopenharmony_ci            result = predicate()
3577db96d56Sopenharmony_ci        return result
3587db96d56Sopenharmony_ci
3597db96d56Sopenharmony_ci    def notify(self, n=1):
3607db96d56Sopenharmony_ci        """Wake up one or more threads waiting on this condition, if any.
3617db96d56Sopenharmony_ci
3627db96d56Sopenharmony_ci        If the calling thread has not acquired the lock when this method is
3637db96d56Sopenharmony_ci        called, a RuntimeError is raised.
3647db96d56Sopenharmony_ci
3657db96d56Sopenharmony_ci        This method wakes up at most n of the threads waiting for the condition
3667db96d56Sopenharmony_ci        variable; it is a no-op if no threads are waiting.
3677db96d56Sopenharmony_ci
3687db96d56Sopenharmony_ci        """
3697db96d56Sopenharmony_ci        if not self._is_owned():
3707db96d56Sopenharmony_ci            raise RuntimeError("cannot notify on un-acquired lock")
3717db96d56Sopenharmony_ci        waiters = self._waiters
3727db96d56Sopenharmony_ci        while waiters and n > 0:
3737db96d56Sopenharmony_ci            waiter = waiters[0]
3747db96d56Sopenharmony_ci            try:
3757db96d56Sopenharmony_ci                waiter.release()
3767db96d56Sopenharmony_ci            except RuntimeError:
3777db96d56Sopenharmony_ci                # gh-92530: The previous call of notify() released the lock,
3787db96d56Sopenharmony_ci                # but was interrupted before removing it from the queue.
3797db96d56Sopenharmony_ci                # It can happen if a signal handler raises an exception,
3807db96d56Sopenharmony_ci                # like CTRL+C which raises KeyboardInterrupt.
3817db96d56Sopenharmony_ci                pass
3827db96d56Sopenharmony_ci            else:
3837db96d56Sopenharmony_ci                n -= 1
3847db96d56Sopenharmony_ci            try:
3857db96d56Sopenharmony_ci                waiters.remove(waiter)
3867db96d56Sopenharmony_ci            except ValueError:
3877db96d56Sopenharmony_ci                pass
3887db96d56Sopenharmony_ci
3897db96d56Sopenharmony_ci    def notify_all(self):
3907db96d56Sopenharmony_ci        """Wake up all threads waiting on this condition.
3917db96d56Sopenharmony_ci
3927db96d56Sopenharmony_ci        If the calling thread has not acquired the lock when this method
3937db96d56Sopenharmony_ci        is called, a RuntimeError is raised.
3947db96d56Sopenharmony_ci
3957db96d56Sopenharmony_ci        """
3967db96d56Sopenharmony_ci        self.notify(len(self._waiters))
3977db96d56Sopenharmony_ci
3987db96d56Sopenharmony_ci    def notifyAll(self):
3997db96d56Sopenharmony_ci        """Wake up all threads waiting on this condition.
4007db96d56Sopenharmony_ci
4017db96d56Sopenharmony_ci        This method is deprecated, use notify_all() instead.
4027db96d56Sopenharmony_ci
4037db96d56Sopenharmony_ci        """
4047db96d56Sopenharmony_ci        import warnings
4057db96d56Sopenharmony_ci        warnings.warn('notifyAll() is deprecated, use notify_all() instead',
4067db96d56Sopenharmony_ci                      DeprecationWarning, stacklevel=2)
4077db96d56Sopenharmony_ci        self.notify_all()
4087db96d56Sopenharmony_ci
4097db96d56Sopenharmony_ci
4107db96d56Sopenharmony_ciclass Semaphore:
4117db96d56Sopenharmony_ci    """This class implements semaphore objects.
4127db96d56Sopenharmony_ci
4137db96d56Sopenharmony_ci    Semaphores manage a counter representing the number of release() calls minus
4147db96d56Sopenharmony_ci    the number of acquire() calls, plus an initial value. The acquire() method
4157db96d56Sopenharmony_ci    blocks if necessary until it can return without making the counter
4167db96d56Sopenharmony_ci    negative. If not given, value defaults to 1.
4177db96d56Sopenharmony_ci
4187db96d56Sopenharmony_ci    """
4197db96d56Sopenharmony_ci
4207db96d56Sopenharmony_ci    # After Tim Peters' semaphore class, but not quite the same (no maximum)
4217db96d56Sopenharmony_ci
4227db96d56Sopenharmony_ci    def __init__(self, value=1):
4237db96d56Sopenharmony_ci        if value < 0:
4247db96d56Sopenharmony_ci            raise ValueError("semaphore initial value must be >= 0")
4257db96d56Sopenharmony_ci        self._cond = Condition(Lock())
4267db96d56Sopenharmony_ci        self._value = value
4277db96d56Sopenharmony_ci
4287db96d56Sopenharmony_ci    def __repr__(self):
4297db96d56Sopenharmony_ci        cls = self.__class__
4307db96d56Sopenharmony_ci        return (f"<{cls.__module__}.{cls.__qualname__} at {id(self):#x}:"
4317db96d56Sopenharmony_ci                f" value={self._value}>")
4327db96d56Sopenharmony_ci
4337db96d56Sopenharmony_ci    def acquire(self, blocking=True, timeout=None):
4347db96d56Sopenharmony_ci        """Acquire a semaphore, decrementing the internal counter by one.
4357db96d56Sopenharmony_ci
4367db96d56Sopenharmony_ci        When invoked without arguments: if the internal counter is larger than
4377db96d56Sopenharmony_ci        zero on entry, decrement it by one and return immediately. If it is zero
4387db96d56Sopenharmony_ci        on entry, block, waiting until some other thread has called release() to
4397db96d56Sopenharmony_ci        make it larger than zero. This is done with proper interlocking so that
4407db96d56Sopenharmony_ci        if multiple acquire() calls are blocked, release() will wake exactly one
4417db96d56Sopenharmony_ci        of them up. The implementation may pick one at random, so the order in
4427db96d56Sopenharmony_ci        which blocked threads are awakened should not be relied on. There is no
4437db96d56Sopenharmony_ci        return value in this case.
4447db96d56Sopenharmony_ci
4457db96d56Sopenharmony_ci        When invoked with blocking set to true, do the same thing as when called
4467db96d56Sopenharmony_ci        without arguments, and return true.
4477db96d56Sopenharmony_ci
4487db96d56Sopenharmony_ci        When invoked with blocking set to false, do not block. If a call without
4497db96d56Sopenharmony_ci        an argument would block, return false immediately; otherwise, do the
4507db96d56Sopenharmony_ci        same thing as when called without arguments, and return true.
4517db96d56Sopenharmony_ci
4527db96d56Sopenharmony_ci        When invoked with a timeout other than None, it will block for at
4537db96d56Sopenharmony_ci        most timeout seconds.  If acquire does not complete successfully in
4547db96d56Sopenharmony_ci        that interval, return false.  Return true otherwise.
4557db96d56Sopenharmony_ci
4567db96d56Sopenharmony_ci        """
4577db96d56Sopenharmony_ci        if not blocking and timeout is not None:
4587db96d56Sopenharmony_ci            raise ValueError("can't specify timeout for non-blocking acquire")
4597db96d56Sopenharmony_ci        rc = False
4607db96d56Sopenharmony_ci        endtime = None
4617db96d56Sopenharmony_ci        with self._cond:
4627db96d56Sopenharmony_ci            while self._value == 0:
4637db96d56Sopenharmony_ci                if not blocking:
4647db96d56Sopenharmony_ci                    break
4657db96d56Sopenharmony_ci                if timeout is not None:
4667db96d56Sopenharmony_ci                    if endtime is None:
4677db96d56Sopenharmony_ci                        endtime = _time() + timeout
4687db96d56Sopenharmony_ci                    else:
4697db96d56Sopenharmony_ci                        timeout = endtime - _time()
4707db96d56Sopenharmony_ci                        if timeout <= 0:
4717db96d56Sopenharmony_ci                            break
4727db96d56Sopenharmony_ci                self._cond.wait(timeout)
4737db96d56Sopenharmony_ci            else:
4747db96d56Sopenharmony_ci                self._value -= 1
4757db96d56Sopenharmony_ci                rc = True
4767db96d56Sopenharmony_ci        return rc
4777db96d56Sopenharmony_ci
4787db96d56Sopenharmony_ci    __enter__ = acquire
4797db96d56Sopenharmony_ci
4807db96d56Sopenharmony_ci    def release(self, n=1):
4817db96d56Sopenharmony_ci        """Release a semaphore, incrementing the internal counter by one or more.
4827db96d56Sopenharmony_ci
4837db96d56Sopenharmony_ci        When the counter is zero on entry and another thread is waiting for it
4847db96d56Sopenharmony_ci        to become larger than zero again, wake up that thread.
4857db96d56Sopenharmony_ci
4867db96d56Sopenharmony_ci        """
4877db96d56Sopenharmony_ci        if n < 1:
4887db96d56Sopenharmony_ci            raise ValueError('n must be one or more')
4897db96d56Sopenharmony_ci        with self._cond:
4907db96d56Sopenharmony_ci            self._value += n
4917db96d56Sopenharmony_ci            for i in range(n):
4927db96d56Sopenharmony_ci                self._cond.notify()
4937db96d56Sopenharmony_ci
4947db96d56Sopenharmony_ci    def __exit__(self, t, v, tb):
4957db96d56Sopenharmony_ci        self.release()
4967db96d56Sopenharmony_ci
4977db96d56Sopenharmony_ci
4987db96d56Sopenharmony_ciclass BoundedSemaphore(Semaphore):
4997db96d56Sopenharmony_ci    """Implements a bounded semaphore.
5007db96d56Sopenharmony_ci
5017db96d56Sopenharmony_ci    A bounded semaphore checks to make sure its current value doesn't exceed its
5027db96d56Sopenharmony_ci    initial value. If it does, ValueError is raised. In most situations
5037db96d56Sopenharmony_ci    semaphores are used to guard resources with limited capacity.
5047db96d56Sopenharmony_ci
5057db96d56Sopenharmony_ci    If the semaphore is released too many times it's a sign of a bug. If not
5067db96d56Sopenharmony_ci    given, value defaults to 1.
5077db96d56Sopenharmony_ci
5087db96d56Sopenharmony_ci    Like regular semaphores, bounded semaphores manage a counter representing
5097db96d56Sopenharmony_ci    the number of release() calls minus the number of acquire() calls, plus an
5107db96d56Sopenharmony_ci    initial value. The acquire() method blocks if necessary until it can return
5117db96d56Sopenharmony_ci    without making the counter negative. If not given, value defaults to 1.
5127db96d56Sopenharmony_ci
5137db96d56Sopenharmony_ci    """
5147db96d56Sopenharmony_ci
5157db96d56Sopenharmony_ci    def __init__(self, value=1):
5167db96d56Sopenharmony_ci        Semaphore.__init__(self, value)
5177db96d56Sopenharmony_ci        self._initial_value = value
5187db96d56Sopenharmony_ci
5197db96d56Sopenharmony_ci    def __repr__(self):
5207db96d56Sopenharmony_ci        cls = self.__class__
5217db96d56Sopenharmony_ci        return (f"<{cls.__module__}.{cls.__qualname__} at {id(self):#x}:"
5227db96d56Sopenharmony_ci                f" value={self._value}/{self._initial_value}>")
5237db96d56Sopenharmony_ci
5247db96d56Sopenharmony_ci    def release(self, n=1):
5257db96d56Sopenharmony_ci        """Release a semaphore, incrementing the internal counter by one or more.
5267db96d56Sopenharmony_ci
5277db96d56Sopenharmony_ci        When the counter is zero on entry and another thread is waiting for it
5287db96d56Sopenharmony_ci        to become larger than zero again, wake up that thread.
5297db96d56Sopenharmony_ci
5307db96d56Sopenharmony_ci        If the number of releases exceeds the number of acquires,
5317db96d56Sopenharmony_ci        raise a ValueError.
5327db96d56Sopenharmony_ci
5337db96d56Sopenharmony_ci        """
5347db96d56Sopenharmony_ci        if n < 1:
5357db96d56Sopenharmony_ci            raise ValueError('n must be one or more')
5367db96d56Sopenharmony_ci        with self._cond:
5377db96d56Sopenharmony_ci            if self._value + n > self._initial_value:
5387db96d56Sopenharmony_ci                raise ValueError("Semaphore released too many times")
5397db96d56Sopenharmony_ci            self._value += n
5407db96d56Sopenharmony_ci            for i in range(n):
5417db96d56Sopenharmony_ci                self._cond.notify()
5427db96d56Sopenharmony_ci
5437db96d56Sopenharmony_ci
5447db96d56Sopenharmony_ciclass Event:
5457db96d56Sopenharmony_ci    """Class implementing event objects.
5467db96d56Sopenharmony_ci
5477db96d56Sopenharmony_ci    Events manage a flag that can be set to true with the set() method and reset
5487db96d56Sopenharmony_ci    to false with the clear() method. The wait() method blocks until the flag is
5497db96d56Sopenharmony_ci    true.  The flag is initially false.
5507db96d56Sopenharmony_ci
5517db96d56Sopenharmony_ci    """
5527db96d56Sopenharmony_ci
5537db96d56Sopenharmony_ci    # After Tim Peters' event class (without is_posted())
5547db96d56Sopenharmony_ci
5557db96d56Sopenharmony_ci    def __init__(self):
5567db96d56Sopenharmony_ci        self._cond = Condition(Lock())
5577db96d56Sopenharmony_ci        self._flag = False
5587db96d56Sopenharmony_ci
5597db96d56Sopenharmony_ci    def __repr__(self):
5607db96d56Sopenharmony_ci        cls = self.__class__
5617db96d56Sopenharmony_ci        status = 'set' if self._flag else 'unset'
5627db96d56Sopenharmony_ci        return f"<{cls.__module__}.{cls.__qualname__} at {id(self):#x}: {status}>"
5637db96d56Sopenharmony_ci
5647db96d56Sopenharmony_ci    def _at_fork_reinit(self):
5657db96d56Sopenharmony_ci        # Private method called by Thread._reset_internal_locks()
5667db96d56Sopenharmony_ci        self._cond._at_fork_reinit()
5677db96d56Sopenharmony_ci
5687db96d56Sopenharmony_ci    def is_set(self):
5697db96d56Sopenharmony_ci        """Return true if and only if the internal flag is true."""
5707db96d56Sopenharmony_ci        return self._flag
5717db96d56Sopenharmony_ci
5727db96d56Sopenharmony_ci    def isSet(self):
5737db96d56Sopenharmony_ci        """Return true if and only if the internal flag is true.
5747db96d56Sopenharmony_ci
5757db96d56Sopenharmony_ci        This method is deprecated, use is_set() instead.
5767db96d56Sopenharmony_ci
5777db96d56Sopenharmony_ci        """
5787db96d56Sopenharmony_ci        import warnings
5797db96d56Sopenharmony_ci        warnings.warn('isSet() is deprecated, use is_set() instead',
5807db96d56Sopenharmony_ci                      DeprecationWarning, stacklevel=2)
5817db96d56Sopenharmony_ci        return self.is_set()
5827db96d56Sopenharmony_ci
5837db96d56Sopenharmony_ci    def set(self):
5847db96d56Sopenharmony_ci        """Set the internal flag to true.
5857db96d56Sopenharmony_ci
5867db96d56Sopenharmony_ci        All threads waiting for it to become true are awakened. Threads
5877db96d56Sopenharmony_ci        that call wait() once the flag is true will not block at all.
5887db96d56Sopenharmony_ci
5897db96d56Sopenharmony_ci        """
5907db96d56Sopenharmony_ci        with self._cond:
5917db96d56Sopenharmony_ci            self._flag = True
5927db96d56Sopenharmony_ci            self._cond.notify_all()
5937db96d56Sopenharmony_ci
5947db96d56Sopenharmony_ci    def clear(self):
5957db96d56Sopenharmony_ci        """Reset the internal flag to false.
5967db96d56Sopenharmony_ci
5977db96d56Sopenharmony_ci        Subsequently, threads calling wait() will block until set() is called to
5987db96d56Sopenharmony_ci        set the internal flag to true again.
5997db96d56Sopenharmony_ci
6007db96d56Sopenharmony_ci        """
6017db96d56Sopenharmony_ci        with self._cond:
6027db96d56Sopenharmony_ci            self._flag = False
6037db96d56Sopenharmony_ci
6047db96d56Sopenharmony_ci    def wait(self, timeout=None):
6057db96d56Sopenharmony_ci        """Block until the internal flag is true.
6067db96d56Sopenharmony_ci
6077db96d56Sopenharmony_ci        If the internal flag is true on entry, return immediately. Otherwise,
6087db96d56Sopenharmony_ci        block until another thread calls set() to set the flag to true, or until
6097db96d56Sopenharmony_ci        the optional timeout occurs.
6107db96d56Sopenharmony_ci
6117db96d56Sopenharmony_ci        When the timeout argument is present and not None, it should be a
6127db96d56Sopenharmony_ci        floating point number specifying a timeout for the operation in seconds
6137db96d56Sopenharmony_ci        (or fractions thereof).
6147db96d56Sopenharmony_ci
6157db96d56Sopenharmony_ci        This method returns the internal flag on exit, so it will always return
6167db96d56Sopenharmony_ci        True except if a timeout is given and the operation times out.
6177db96d56Sopenharmony_ci
6187db96d56Sopenharmony_ci        """
6197db96d56Sopenharmony_ci        with self._cond:
6207db96d56Sopenharmony_ci            signaled = self._flag
6217db96d56Sopenharmony_ci            if not signaled:
6227db96d56Sopenharmony_ci                signaled = self._cond.wait(timeout)
6237db96d56Sopenharmony_ci            return signaled
6247db96d56Sopenharmony_ci
6257db96d56Sopenharmony_ci
6267db96d56Sopenharmony_ci# A barrier class.  Inspired in part by the pthread_barrier_* api and
6277db96d56Sopenharmony_ci# the CyclicBarrier class from Java.  See
6287db96d56Sopenharmony_ci# http://sourceware.org/pthreads-win32/manual/pthread_barrier_init.html and
6297db96d56Sopenharmony_ci# http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/
6307db96d56Sopenharmony_ci#        CyclicBarrier.html
6317db96d56Sopenharmony_ci# for information.
6327db96d56Sopenharmony_ci# We maintain two main states, 'filling' and 'draining' enabling the barrier
6337db96d56Sopenharmony_ci# to be cyclic.  Threads are not allowed into it until it has fully drained
6347db96d56Sopenharmony_ci# since the previous cycle.  In addition, a 'resetting' state exists which is
6357db96d56Sopenharmony_ci# similar to 'draining' except that threads leave with a BrokenBarrierError,
6367db96d56Sopenharmony_ci# and a 'broken' state in which all threads get the exception.
6377db96d56Sopenharmony_ciclass Barrier:
6387db96d56Sopenharmony_ci    """Implements a Barrier.
6397db96d56Sopenharmony_ci
6407db96d56Sopenharmony_ci    Useful for synchronizing a fixed number of threads at known synchronization
6417db96d56Sopenharmony_ci    points.  Threads block on 'wait()' and are simultaneously awoken once they
6427db96d56Sopenharmony_ci    have all made that call.
6437db96d56Sopenharmony_ci
6447db96d56Sopenharmony_ci    """
6457db96d56Sopenharmony_ci
6467db96d56Sopenharmony_ci    def __init__(self, parties, action=None, timeout=None):
6477db96d56Sopenharmony_ci        """Create a barrier, initialised to 'parties' threads.
6487db96d56Sopenharmony_ci
6497db96d56Sopenharmony_ci        'action' is a callable which, when supplied, will be called by one of
6507db96d56Sopenharmony_ci        the threads after they have all entered the barrier and just prior to
6517db96d56Sopenharmony_ci        releasing them all. If a 'timeout' is provided, it is used as the
6527db96d56Sopenharmony_ci        default for all subsequent 'wait()' calls.
6537db96d56Sopenharmony_ci
6547db96d56Sopenharmony_ci        """
6557db96d56Sopenharmony_ci        self._cond = Condition(Lock())
6567db96d56Sopenharmony_ci        self._action = action
6577db96d56Sopenharmony_ci        self._timeout = timeout
6587db96d56Sopenharmony_ci        self._parties = parties
6597db96d56Sopenharmony_ci        self._state = 0  # 0 filling, 1 draining, -1 resetting, -2 broken
6607db96d56Sopenharmony_ci        self._count = 0
6617db96d56Sopenharmony_ci
6627db96d56Sopenharmony_ci    def __repr__(self):
6637db96d56Sopenharmony_ci        cls = self.__class__
6647db96d56Sopenharmony_ci        if self.broken:
6657db96d56Sopenharmony_ci            return f"<{cls.__module__}.{cls.__qualname__} at {id(self):#x}: broken>"
6667db96d56Sopenharmony_ci        return (f"<{cls.__module__}.{cls.__qualname__} at {id(self):#x}:"
6677db96d56Sopenharmony_ci                f" waiters={self.n_waiting}/{self.parties}>")
6687db96d56Sopenharmony_ci
6697db96d56Sopenharmony_ci    def wait(self, timeout=None):
6707db96d56Sopenharmony_ci        """Wait for the barrier.
6717db96d56Sopenharmony_ci
6727db96d56Sopenharmony_ci        When the specified number of threads have started waiting, they are all
6737db96d56Sopenharmony_ci        simultaneously awoken. If an 'action' was provided for the barrier, one
6747db96d56Sopenharmony_ci        of the threads will have executed that callback prior to returning.
6757db96d56Sopenharmony_ci        Returns an individual index number from 0 to 'parties-1'.
6767db96d56Sopenharmony_ci
6777db96d56Sopenharmony_ci        """
6787db96d56Sopenharmony_ci        if timeout is None:
6797db96d56Sopenharmony_ci            timeout = self._timeout
6807db96d56Sopenharmony_ci        with self._cond:
6817db96d56Sopenharmony_ci            self._enter() # Block while the barrier drains.
6827db96d56Sopenharmony_ci            index = self._count
6837db96d56Sopenharmony_ci            self._count += 1
6847db96d56Sopenharmony_ci            try:
6857db96d56Sopenharmony_ci                if index + 1 == self._parties:
6867db96d56Sopenharmony_ci                    # We release the barrier
6877db96d56Sopenharmony_ci                    self._release()
6887db96d56Sopenharmony_ci                else:
6897db96d56Sopenharmony_ci                    # We wait until someone releases us
6907db96d56Sopenharmony_ci                    self._wait(timeout)
6917db96d56Sopenharmony_ci                return index
6927db96d56Sopenharmony_ci            finally:
6937db96d56Sopenharmony_ci                self._count -= 1
6947db96d56Sopenharmony_ci                # Wake up any threads waiting for barrier to drain.
6957db96d56Sopenharmony_ci                self._exit()
6967db96d56Sopenharmony_ci
6977db96d56Sopenharmony_ci    # Block until the barrier is ready for us, or raise an exception
6987db96d56Sopenharmony_ci    # if it is broken.
6997db96d56Sopenharmony_ci    def _enter(self):
7007db96d56Sopenharmony_ci        while self._state in (-1, 1):
7017db96d56Sopenharmony_ci            # It is draining or resetting, wait until done
7027db96d56Sopenharmony_ci            self._cond.wait()
7037db96d56Sopenharmony_ci        #see if the barrier is in a broken state
7047db96d56Sopenharmony_ci        if self._state < 0:
7057db96d56Sopenharmony_ci            raise BrokenBarrierError
7067db96d56Sopenharmony_ci        assert self._state == 0
7077db96d56Sopenharmony_ci
7087db96d56Sopenharmony_ci    # Optionally run the 'action' and release the threads waiting
7097db96d56Sopenharmony_ci    # in the barrier.
7107db96d56Sopenharmony_ci    def _release(self):
7117db96d56Sopenharmony_ci        try:
7127db96d56Sopenharmony_ci            if self._action:
7137db96d56Sopenharmony_ci                self._action()
7147db96d56Sopenharmony_ci            # enter draining state
7157db96d56Sopenharmony_ci            self._state = 1
7167db96d56Sopenharmony_ci            self._cond.notify_all()
7177db96d56Sopenharmony_ci        except:
7187db96d56Sopenharmony_ci            #an exception during the _action handler.  Break and reraise
7197db96d56Sopenharmony_ci            self._break()
7207db96d56Sopenharmony_ci            raise
7217db96d56Sopenharmony_ci
7227db96d56Sopenharmony_ci    # Wait in the barrier until we are released.  Raise an exception
7237db96d56Sopenharmony_ci    # if the barrier is reset or broken.
7247db96d56Sopenharmony_ci    def _wait(self, timeout):
7257db96d56Sopenharmony_ci        if not self._cond.wait_for(lambda : self._state != 0, timeout):
7267db96d56Sopenharmony_ci            #timed out.  Break the barrier
7277db96d56Sopenharmony_ci            self._break()
7287db96d56Sopenharmony_ci            raise BrokenBarrierError
7297db96d56Sopenharmony_ci        if self._state < 0:
7307db96d56Sopenharmony_ci            raise BrokenBarrierError
7317db96d56Sopenharmony_ci        assert self._state == 1
7327db96d56Sopenharmony_ci
7337db96d56Sopenharmony_ci    # If we are the last thread to exit the barrier, signal any threads
7347db96d56Sopenharmony_ci    # waiting for the barrier to drain.
7357db96d56Sopenharmony_ci    def _exit(self):
7367db96d56Sopenharmony_ci        if self._count == 0:
7377db96d56Sopenharmony_ci            if self._state in (-1, 1):
7387db96d56Sopenharmony_ci                #resetting or draining
7397db96d56Sopenharmony_ci                self._state = 0
7407db96d56Sopenharmony_ci                self._cond.notify_all()
7417db96d56Sopenharmony_ci
7427db96d56Sopenharmony_ci    def reset(self):
7437db96d56Sopenharmony_ci        """Reset the barrier to the initial state.
7447db96d56Sopenharmony_ci
7457db96d56Sopenharmony_ci        Any threads currently waiting will get the BrokenBarrier exception
7467db96d56Sopenharmony_ci        raised.
7477db96d56Sopenharmony_ci
7487db96d56Sopenharmony_ci        """
7497db96d56Sopenharmony_ci        with self._cond:
7507db96d56Sopenharmony_ci            if self._count > 0:
7517db96d56Sopenharmony_ci                if self._state == 0:
7527db96d56Sopenharmony_ci                    #reset the barrier, waking up threads
7537db96d56Sopenharmony_ci                    self._state = -1
7547db96d56Sopenharmony_ci                elif self._state == -2:
7557db96d56Sopenharmony_ci                    #was broken, set it to reset state
7567db96d56Sopenharmony_ci                    #which clears when the last thread exits
7577db96d56Sopenharmony_ci                    self._state = -1
7587db96d56Sopenharmony_ci            else:
7597db96d56Sopenharmony_ci                self._state = 0
7607db96d56Sopenharmony_ci            self._cond.notify_all()
7617db96d56Sopenharmony_ci
7627db96d56Sopenharmony_ci    def abort(self):
7637db96d56Sopenharmony_ci        """Place the barrier into a 'broken' state.
7647db96d56Sopenharmony_ci
7657db96d56Sopenharmony_ci        Useful in case of error.  Any currently waiting threads and threads
7667db96d56Sopenharmony_ci        attempting to 'wait()' will have BrokenBarrierError raised.
7677db96d56Sopenharmony_ci
7687db96d56Sopenharmony_ci        """
7697db96d56Sopenharmony_ci        with self._cond:
7707db96d56Sopenharmony_ci            self._break()
7717db96d56Sopenharmony_ci
7727db96d56Sopenharmony_ci    def _break(self):
7737db96d56Sopenharmony_ci        # An internal error was detected.  The barrier is set to
7747db96d56Sopenharmony_ci        # a broken state all parties awakened.
7757db96d56Sopenharmony_ci        self._state = -2
7767db96d56Sopenharmony_ci        self._cond.notify_all()
7777db96d56Sopenharmony_ci
7787db96d56Sopenharmony_ci    @property
7797db96d56Sopenharmony_ci    def parties(self):
7807db96d56Sopenharmony_ci        """Return the number of threads required to trip the barrier."""
7817db96d56Sopenharmony_ci        return self._parties
7827db96d56Sopenharmony_ci
7837db96d56Sopenharmony_ci    @property
7847db96d56Sopenharmony_ci    def n_waiting(self):
7857db96d56Sopenharmony_ci        """Return the number of threads currently waiting at the barrier."""
7867db96d56Sopenharmony_ci        # We don't need synchronization here since this is an ephemeral result
7877db96d56Sopenharmony_ci        # anyway.  It returns the correct value in the steady state.
7887db96d56Sopenharmony_ci        if self._state == 0:
7897db96d56Sopenharmony_ci            return self._count
7907db96d56Sopenharmony_ci        return 0
7917db96d56Sopenharmony_ci
7927db96d56Sopenharmony_ci    @property
7937db96d56Sopenharmony_ci    def broken(self):
7947db96d56Sopenharmony_ci        """Return True if the barrier is in a broken state."""
7957db96d56Sopenharmony_ci        return self._state == -2
7967db96d56Sopenharmony_ci
7977db96d56Sopenharmony_ci# exception raised by the Barrier class
7987db96d56Sopenharmony_ciclass BrokenBarrierError(RuntimeError):
7997db96d56Sopenharmony_ci    pass
8007db96d56Sopenharmony_ci
8017db96d56Sopenharmony_ci
8027db96d56Sopenharmony_ci# Helper to generate new thread names
8037db96d56Sopenharmony_ci_counter = _count(1).__next__
8047db96d56Sopenharmony_cidef _newname(name_template):
8057db96d56Sopenharmony_ci    return name_template % _counter()
8067db96d56Sopenharmony_ci
8077db96d56Sopenharmony_ci# Active thread administration.
8087db96d56Sopenharmony_ci#
8097db96d56Sopenharmony_ci# bpo-44422: Use a reentrant lock to allow reentrant calls to functions like
8107db96d56Sopenharmony_ci# threading.enumerate().
8117db96d56Sopenharmony_ci_active_limbo_lock = RLock()
8127db96d56Sopenharmony_ci_active = {}    # maps thread id to Thread object
8137db96d56Sopenharmony_ci_limbo = {}
8147db96d56Sopenharmony_ci_dangling = WeakSet()
8157db96d56Sopenharmony_ci
8167db96d56Sopenharmony_ci# Set of Thread._tstate_lock locks of non-daemon threads used by _shutdown()
8177db96d56Sopenharmony_ci# to wait until all Python thread states get deleted:
8187db96d56Sopenharmony_ci# see Thread._set_tstate_lock().
8197db96d56Sopenharmony_ci_shutdown_locks_lock = _allocate_lock()
8207db96d56Sopenharmony_ci_shutdown_locks = set()
8217db96d56Sopenharmony_ci
8227db96d56Sopenharmony_cidef _maintain_shutdown_locks():
8237db96d56Sopenharmony_ci    """
8247db96d56Sopenharmony_ci    Drop any shutdown locks that don't correspond to running threads anymore.
8257db96d56Sopenharmony_ci
8267db96d56Sopenharmony_ci    Calling this from time to time avoids an ever-growing _shutdown_locks
8277db96d56Sopenharmony_ci    set when Thread objects are not joined explicitly. See bpo-37788.
8287db96d56Sopenharmony_ci
8297db96d56Sopenharmony_ci    This must be called with _shutdown_locks_lock acquired.
8307db96d56Sopenharmony_ci    """
8317db96d56Sopenharmony_ci    # If a lock was released, the corresponding thread has exited
8327db96d56Sopenharmony_ci    to_remove = [lock for lock in _shutdown_locks if not lock.locked()]
8337db96d56Sopenharmony_ci    _shutdown_locks.difference_update(to_remove)
8347db96d56Sopenharmony_ci
8357db96d56Sopenharmony_ci
8367db96d56Sopenharmony_ci# Main class for threads
8377db96d56Sopenharmony_ci
8387db96d56Sopenharmony_ciclass Thread:
8397db96d56Sopenharmony_ci    """A class that represents a thread of control.
8407db96d56Sopenharmony_ci
8417db96d56Sopenharmony_ci    This class can be safely subclassed in a limited fashion. There are two ways
8427db96d56Sopenharmony_ci    to specify the activity: by passing a callable object to the constructor, or
8437db96d56Sopenharmony_ci    by overriding the run() method in a subclass.
8447db96d56Sopenharmony_ci
8457db96d56Sopenharmony_ci    """
8467db96d56Sopenharmony_ci
8477db96d56Sopenharmony_ci    _initialized = False
8487db96d56Sopenharmony_ci
8497db96d56Sopenharmony_ci    def __init__(self, group=None, target=None, name=None,
8507db96d56Sopenharmony_ci                 args=(), kwargs=None, *, daemon=None):
8517db96d56Sopenharmony_ci        """This constructor should always be called with keyword arguments. Arguments are:
8527db96d56Sopenharmony_ci
8537db96d56Sopenharmony_ci        *group* should be None; reserved for future extension when a ThreadGroup
8547db96d56Sopenharmony_ci        class is implemented.
8557db96d56Sopenharmony_ci
8567db96d56Sopenharmony_ci        *target* is the callable object to be invoked by the run()
8577db96d56Sopenharmony_ci        method. Defaults to None, meaning nothing is called.
8587db96d56Sopenharmony_ci
8597db96d56Sopenharmony_ci        *name* is the thread name. By default, a unique name is constructed of
8607db96d56Sopenharmony_ci        the form "Thread-N" where N is a small decimal number.
8617db96d56Sopenharmony_ci
8627db96d56Sopenharmony_ci        *args* is a list or tuple of arguments for the target invocation. Defaults to ().
8637db96d56Sopenharmony_ci
8647db96d56Sopenharmony_ci        *kwargs* is a dictionary of keyword arguments for the target
8657db96d56Sopenharmony_ci        invocation. Defaults to {}.
8667db96d56Sopenharmony_ci
8677db96d56Sopenharmony_ci        If a subclass overrides the constructor, it must make sure to invoke
8687db96d56Sopenharmony_ci        the base class constructor (Thread.__init__()) before doing anything
8697db96d56Sopenharmony_ci        else to the thread.
8707db96d56Sopenharmony_ci
8717db96d56Sopenharmony_ci        """
8727db96d56Sopenharmony_ci        assert group is None, "group argument must be None for now"
8737db96d56Sopenharmony_ci        if kwargs is None:
8747db96d56Sopenharmony_ci            kwargs = {}
8757db96d56Sopenharmony_ci        if name:
8767db96d56Sopenharmony_ci            name = str(name)
8777db96d56Sopenharmony_ci        else:
8787db96d56Sopenharmony_ci            name = _newname("Thread-%d")
8797db96d56Sopenharmony_ci            if target is not None:
8807db96d56Sopenharmony_ci                try:
8817db96d56Sopenharmony_ci                    target_name = target.__name__
8827db96d56Sopenharmony_ci                    name += f" ({target_name})"
8837db96d56Sopenharmony_ci                except AttributeError:
8847db96d56Sopenharmony_ci                    pass
8857db96d56Sopenharmony_ci
8867db96d56Sopenharmony_ci        self._target = target
8877db96d56Sopenharmony_ci        self._name = name
8887db96d56Sopenharmony_ci        self._args = args
8897db96d56Sopenharmony_ci        self._kwargs = kwargs
8907db96d56Sopenharmony_ci        if daemon is not None:
8917db96d56Sopenharmony_ci            self._daemonic = daemon
8927db96d56Sopenharmony_ci        else:
8937db96d56Sopenharmony_ci            self._daemonic = current_thread().daemon
8947db96d56Sopenharmony_ci        self._ident = None
8957db96d56Sopenharmony_ci        if _HAVE_THREAD_NATIVE_ID:
8967db96d56Sopenharmony_ci            self._native_id = None
8977db96d56Sopenharmony_ci        self._tstate_lock = None
8987db96d56Sopenharmony_ci        self._started = Event()
8997db96d56Sopenharmony_ci        self._is_stopped = False
9007db96d56Sopenharmony_ci        self._initialized = True
9017db96d56Sopenharmony_ci        # Copy of sys.stderr used by self._invoke_excepthook()
9027db96d56Sopenharmony_ci        self._stderr = _sys.stderr
9037db96d56Sopenharmony_ci        self._invoke_excepthook = _make_invoke_excepthook()
9047db96d56Sopenharmony_ci        # For debugging and _after_fork()
9057db96d56Sopenharmony_ci        _dangling.add(self)
9067db96d56Sopenharmony_ci
9077db96d56Sopenharmony_ci    def _reset_internal_locks(self, is_alive):
9087db96d56Sopenharmony_ci        # private!  Called by _after_fork() to reset our internal locks as
9097db96d56Sopenharmony_ci        # they may be in an invalid state leading to a deadlock or crash.
9107db96d56Sopenharmony_ci        self._started._at_fork_reinit()
9117db96d56Sopenharmony_ci        if is_alive:
9127db96d56Sopenharmony_ci            # bpo-42350: If the fork happens when the thread is already stopped
9137db96d56Sopenharmony_ci            # (ex: after threading._shutdown() has been called), _tstate_lock
9147db96d56Sopenharmony_ci            # is None. Do nothing in this case.
9157db96d56Sopenharmony_ci            if self._tstate_lock is not None:
9167db96d56Sopenharmony_ci                self._tstate_lock._at_fork_reinit()
9177db96d56Sopenharmony_ci                self._tstate_lock.acquire()
9187db96d56Sopenharmony_ci        else:
9197db96d56Sopenharmony_ci            # The thread isn't alive after fork: it doesn't have a tstate
9207db96d56Sopenharmony_ci            # anymore.
9217db96d56Sopenharmony_ci            self._is_stopped = True
9227db96d56Sopenharmony_ci            self._tstate_lock = None
9237db96d56Sopenharmony_ci
9247db96d56Sopenharmony_ci    def __repr__(self):
9257db96d56Sopenharmony_ci        assert self._initialized, "Thread.__init__() was not called"
9267db96d56Sopenharmony_ci        status = "initial"
9277db96d56Sopenharmony_ci        if self._started.is_set():
9287db96d56Sopenharmony_ci            status = "started"
9297db96d56Sopenharmony_ci        self.is_alive() # easy way to get ._is_stopped set when appropriate
9307db96d56Sopenharmony_ci        if self._is_stopped:
9317db96d56Sopenharmony_ci            status = "stopped"
9327db96d56Sopenharmony_ci        if self._daemonic:
9337db96d56Sopenharmony_ci            status += " daemon"
9347db96d56Sopenharmony_ci        if self._ident is not None:
9357db96d56Sopenharmony_ci            status += " %s" % self._ident
9367db96d56Sopenharmony_ci        return "<%s(%s, %s)>" % (self.__class__.__name__, self._name, status)
9377db96d56Sopenharmony_ci
9387db96d56Sopenharmony_ci    def start(self):
9397db96d56Sopenharmony_ci        """Start the thread's activity.
9407db96d56Sopenharmony_ci
9417db96d56Sopenharmony_ci        It must be called at most once per thread object. It arranges for the
9427db96d56Sopenharmony_ci        object's run() method to be invoked in a separate thread of control.
9437db96d56Sopenharmony_ci
9447db96d56Sopenharmony_ci        This method will raise a RuntimeError if called more than once on the
9457db96d56Sopenharmony_ci        same thread object.
9467db96d56Sopenharmony_ci
9477db96d56Sopenharmony_ci        """
9487db96d56Sopenharmony_ci        if not self._initialized:
9497db96d56Sopenharmony_ci            raise RuntimeError("thread.__init__() not called")
9507db96d56Sopenharmony_ci
9517db96d56Sopenharmony_ci        if self._started.is_set():
9527db96d56Sopenharmony_ci            raise RuntimeError("threads can only be started once")
9537db96d56Sopenharmony_ci
9547db96d56Sopenharmony_ci        with _active_limbo_lock:
9557db96d56Sopenharmony_ci            _limbo[self] = self
9567db96d56Sopenharmony_ci        try:
9577db96d56Sopenharmony_ci            _start_new_thread(self._bootstrap, ())
9587db96d56Sopenharmony_ci        except Exception:
9597db96d56Sopenharmony_ci            with _active_limbo_lock:
9607db96d56Sopenharmony_ci                del _limbo[self]
9617db96d56Sopenharmony_ci            raise
9627db96d56Sopenharmony_ci        self._started.wait()
9637db96d56Sopenharmony_ci
9647db96d56Sopenharmony_ci    def run(self):
9657db96d56Sopenharmony_ci        """Method representing the thread's activity.
9667db96d56Sopenharmony_ci
9677db96d56Sopenharmony_ci        You may override this method in a subclass. The standard run() method
9687db96d56Sopenharmony_ci        invokes the callable object passed to the object's constructor as the
9697db96d56Sopenharmony_ci        target argument, if any, with sequential and keyword arguments taken
9707db96d56Sopenharmony_ci        from the args and kwargs arguments, respectively.
9717db96d56Sopenharmony_ci
9727db96d56Sopenharmony_ci        """
9737db96d56Sopenharmony_ci        try:
9747db96d56Sopenharmony_ci            if self._target is not None:
9757db96d56Sopenharmony_ci                self._target(*self._args, **self._kwargs)
9767db96d56Sopenharmony_ci        finally:
9777db96d56Sopenharmony_ci            # Avoid a refcycle if the thread is running a function with
9787db96d56Sopenharmony_ci            # an argument that has a member that points to the thread.
9797db96d56Sopenharmony_ci            del self._target, self._args, self._kwargs
9807db96d56Sopenharmony_ci
9817db96d56Sopenharmony_ci    def _bootstrap(self):
9827db96d56Sopenharmony_ci        # Wrapper around the real bootstrap code that ignores
9837db96d56Sopenharmony_ci        # exceptions during interpreter cleanup.  Those typically
9847db96d56Sopenharmony_ci        # happen when a daemon thread wakes up at an unfortunate
9857db96d56Sopenharmony_ci        # moment, finds the world around it destroyed, and raises some
9867db96d56Sopenharmony_ci        # random exception *** while trying to report the exception in
9877db96d56Sopenharmony_ci        # _bootstrap_inner() below ***.  Those random exceptions
9887db96d56Sopenharmony_ci        # don't help anybody, and they confuse users, so we suppress
9897db96d56Sopenharmony_ci        # them.  We suppress them only when it appears that the world
9907db96d56Sopenharmony_ci        # indeed has already been destroyed, so that exceptions in
9917db96d56Sopenharmony_ci        # _bootstrap_inner() during normal business hours are properly
9927db96d56Sopenharmony_ci        # reported.  Also, we only suppress them for daemonic threads;
9937db96d56Sopenharmony_ci        # if a non-daemonic encounters this, something else is wrong.
9947db96d56Sopenharmony_ci        try:
9957db96d56Sopenharmony_ci            self._bootstrap_inner()
9967db96d56Sopenharmony_ci        except:
9977db96d56Sopenharmony_ci            if self._daemonic and _sys is None:
9987db96d56Sopenharmony_ci                return
9997db96d56Sopenharmony_ci            raise
10007db96d56Sopenharmony_ci
10017db96d56Sopenharmony_ci    def _set_ident(self):
10027db96d56Sopenharmony_ci        self._ident = get_ident()
10037db96d56Sopenharmony_ci
10047db96d56Sopenharmony_ci    if _HAVE_THREAD_NATIVE_ID:
10057db96d56Sopenharmony_ci        def _set_native_id(self):
10067db96d56Sopenharmony_ci            self._native_id = get_native_id()
10077db96d56Sopenharmony_ci
10087db96d56Sopenharmony_ci    def _set_tstate_lock(self):
10097db96d56Sopenharmony_ci        """
10107db96d56Sopenharmony_ci        Set a lock object which will be released by the interpreter when
10117db96d56Sopenharmony_ci        the underlying thread state (see pystate.h) gets deleted.
10127db96d56Sopenharmony_ci        """
10137db96d56Sopenharmony_ci        self._tstate_lock = _set_sentinel()
10147db96d56Sopenharmony_ci        self._tstate_lock.acquire()
10157db96d56Sopenharmony_ci
10167db96d56Sopenharmony_ci        if not self.daemon:
10177db96d56Sopenharmony_ci            with _shutdown_locks_lock:
10187db96d56Sopenharmony_ci                _maintain_shutdown_locks()
10197db96d56Sopenharmony_ci                _shutdown_locks.add(self._tstate_lock)
10207db96d56Sopenharmony_ci
10217db96d56Sopenharmony_ci    def _bootstrap_inner(self):
10227db96d56Sopenharmony_ci        try:
10237db96d56Sopenharmony_ci            self._set_ident()
10247db96d56Sopenharmony_ci            self._set_tstate_lock()
10257db96d56Sopenharmony_ci            if _HAVE_THREAD_NATIVE_ID:
10267db96d56Sopenharmony_ci                self._set_native_id()
10277db96d56Sopenharmony_ci            self._started.set()
10287db96d56Sopenharmony_ci            with _active_limbo_lock:
10297db96d56Sopenharmony_ci                _active[self._ident] = self
10307db96d56Sopenharmony_ci                del _limbo[self]
10317db96d56Sopenharmony_ci
10327db96d56Sopenharmony_ci            if _trace_hook:
10337db96d56Sopenharmony_ci                _sys.settrace(_trace_hook)
10347db96d56Sopenharmony_ci            if _profile_hook:
10357db96d56Sopenharmony_ci                _sys.setprofile(_profile_hook)
10367db96d56Sopenharmony_ci
10377db96d56Sopenharmony_ci            try:
10387db96d56Sopenharmony_ci                self.run()
10397db96d56Sopenharmony_ci            except:
10407db96d56Sopenharmony_ci                self._invoke_excepthook(self)
10417db96d56Sopenharmony_ci        finally:
10427db96d56Sopenharmony_ci            self._delete()
10437db96d56Sopenharmony_ci
10447db96d56Sopenharmony_ci    def _stop(self):
10457db96d56Sopenharmony_ci        # After calling ._stop(), .is_alive() returns False and .join() returns
10467db96d56Sopenharmony_ci        # immediately.  ._tstate_lock must be released before calling ._stop().
10477db96d56Sopenharmony_ci        #
10487db96d56Sopenharmony_ci        # Normal case:  C code at the end of the thread's life
10497db96d56Sopenharmony_ci        # (release_sentinel in _threadmodule.c) releases ._tstate_lock, and
10507db96d56Sopenharmony_ci        # that's detected by our ._wait_for_tstate_lock(), called by .join()
10517db96d56Sopenharmony_ci        # and .is_alive().  Any number of threads _may_ call ._stop()
10527db96d56Sopenharmony_ci        # simultaneously (for example, if multiple threads are blocked in
10537db96d56Sopenharmony_ci        # .join() calls), and they're not serialized.  That's harmless -
10547db96d56Sopenharmony_ci        # they'll just make redundant rebindings of ._is_stopped and
10557db96d56Sopenharmony_ci        # ._tstate_lock.  Obscure:  we rebind ._tstate_lock last so that the
10567db96d56Sopenharmony_ci        # "assert self._is_stopped" in ._wait_for_tstate_lock() always works
10577db96d56Sopenharmony_ci        # (the assert is executed only if ._tstate_lock is None).
10587db96d56Sopenharmony_ci        #
10597db96d56Sopenharmony_ci        # Special case:  _main_thread releases ._tstate_lock via this
10607db96d56Sopenharmony_ci        # module's _shutdown() function.
10617db96d56Sopenharmony_ci        lock = self._tstate_lock
10627db96d56Sopenharmony_ci        if lock is not None:
10637db96d56Sopenharmony_ci            assert not lock.locked()
10647db96d56Sopenharmony_ci        self._is_stopped = True
10657db96d56Sopenharmony_ci        self._tstate_lock = None
10667db96d56Sopenharmony_ci        if not self.daemon:
10677db96d56Sopenharmony_ci            with _shutdown_locks_lock:
10687db96d56Sopenharmony_ci                # Remove our lock and other released locks from _shutdown_locks
10697db96d56Sopenharmony_ci                _maintain_shutdown_locks()
10707db96d56Sopenharmony_ci
10717db96d56Sopenharmony_ci    def _delete(self):
10727db96d56Sopenharmony_ci        "Remove current thread from the dict of currently running threads."
10737db96d56Sopenharmony_ci        with _active_limbo_lock:
10747db96d56Sopenharmony_ci            del _active[get_ident()]
10757db96d56Sopenharmony_ci            # There must not be any python code between the previous line
10767db96d56Sopenharmony_ci            # and after the lock is released.  Otherwise a tracing function
10777db96d56Sopenharmony_ci            # could try to acquire the lock again in the same thread, (in
10787db96d56Sopenharmony_ci            # current_thread()), and would block.
10797db96d56Sopenharmony_ci
10807db96d56Sopenharmony_ci    def join(self, timeout=None):
10817db96d56Sopenharmony_ci        """Wait until the thread terminates.
10827db96d56Sopenharmony_ci
10837db96d56Sopenharmony_ci        This blocks the calling thread until the thread whose join() method is
10847db96d56Sopenharmony_ci        called terminates -- either normally or through an unhandled exception
10857db96d56Sopenharmony_ci        or until the optional timeout occurs.
10867db96d56Sopenharmony_ci
10877db96d56Sopenharmony_ci        When the timeout argument is present and not None, it should be a
10887db96d56Sopenharmony_ci        floating point number specifying a timeout for the operation in seconds
10897db96d56Sopenharmony_ci        (or fractions thereof). As join() always returns None, you must call
10907db96d56Sopenharmony_ci        is_alive() after join() to decide whether a timeout happened -- if the
10917db96d56Sopenharmony_ci        thread is still alive, the join() call timed out.
10927db96d56Sopenharmony_ci
10937db96d56Sopenharmony_ci        When the timeout argument is not present or None, the operation will
10947db96d56Sopenharmony_ci        block until the thread terminates.
10957db96d56Sopenharmony_ci
10967db96d56Sopenharmony_ci        A thread can be join()ed many times.
10977db96d56Sopenharmony_ci
10987db96d56Sopenharmony_ci        join() raises a RuntimeError if an attempt is made to join the current
10997db96d56Sopenharmony_ci        thread as that would cause a deadlock. It is also an error to join() a
11007db96d56Sopenharmony_ci        thread before it has been started and attempts to do so raises the same
11017db96d56Sopenharmony_ci        exception.
11027db96d56Sopenharmony_ci
11037db96d56Sopenharmony_ci        """
11047db96d56Sopenharmony_ci        if not self._initialized:
11057db96d56Sopenharmony_ci            raise RuntimeError("Thread.__init__() not called")
11067db96d56Sopenharmony_ci        if not self._started.is_set():
11077db96d56Sopenharmony_ci            raise RuntimeError("cannot join thread before it is started")
11087db96d56Sopenharmony_ci        if self is current_thread():
11097db96d56Sopenharmony_ci            raise RuntimeError("cannot join current thread")
11107db96d56Sopenharmony_ci
11117db96d56Sopenharmony_ci        if timeout is None:
11127db96d56Sopenharmony_ci            self._wait_for_tstate_lock()
11137db96d56Sopenharmony_ci        else:
11147db96d56Sopenharmony_ci            # the behavior of a negative timeout isn't documented, but
11157db96d56Sopenharmony_ci            # historically .join(timeout=x) for x<0 has acted as if timeout=0
11167db96d56Sopenharmony_ci            self._wait_for_tstate_lock(timeout=max(timeout, 0))
11177db96d56Sopenharmony_ci
11187db96d56Sopenharmony_ci    def _wait_for_tstate_lock(self, block=True, timeout=-1):
11197db96d56Sopenharmony_ci        # Issue #18808: wait for the thread state to be gone.
11207db96d56Sopenharmony_ci        # At the end of the thread's life, after all knowledge of the thread
11217db96d56Sopenharmony_ci        # is removed from C data structures, C code releases our _tstate_lock.
11227db96d56Sopenharmony_ci        # This method passes its arguments to _tstate_lock.acquire().
11237db96d56Sopenharmony_ci        # If the lock is acquired, the C code is done, and self._stop() is
11247db96d56Sopenharmony_ci        # called.  That sets ._is_stopped to True, and ._tstate_lock to None.
11257db96d56Sopenharmony_ci        lock = self._tstate_lock
11267db96d56Sopenharmony_ci        if lock is None:
11277db96d56Sopenharmony_ci            # already determined that the C code is done
11287db96d56Sopenharmony_ci            assert self._is_stopped
11297db96d56Sopenharmony_ci            return
11307db96d56Sopenharmony_ci
11317db96d56Sopenharmony_ci        try:
11327db96d56Sopenharmony_ci            if lock.acquire(block, timeout):
11337db96d56Sopenharmony_ci                lock.release()
11347db96d56Sopenharmony_ci                self._stop()
11357db96d56Sopenharmony_ci        except:
11367db96d56Sopenharmony_ci            if lock.locked():
11377db96d56Sopenharmony_ci                # bpo-45274: lock.acquire() acquired the lock, but the function
11387db96d56Sopenharmony_ci                # was interrupted with an exception before reaching the
11397db96d56Sopenharmony_ci                # lock.release(). It can happen if a signal handler raises an
11407db96d56Sopenharmony_ci                # exception, like CTRL+C which raises KeyboardInterrupt.
11417db96d56Sopenharmony_ci                lock.release()
11427db96d56Sopenharmony_ci                self._stop()
11437db96d56Sopenharmony_ci            raise
11447db96d56Sopenharmony_ci
11457db96d56Sopenharmony_ci    @property
11467db96d56Sopenharmony_ci    def name(self):
11477db96d56Sopenharmony_ci        """A string used for identification purposes only.
11487db96d56Sopenharmony_ci
11497db96d56Sopenharmony_ci        It has no semantics. Multiple threads may be given the same name. The
11507db96d56Sopenharmony_ci        initial name is set by the constructor.
11517db96d56Sopenharmony_ci
11527db96d56Sopenharmony_ci        """
11537db96d56Sopenharmony_ci        assert self._initialized, "Thread.__init__() not called"
11547db96d56Sopenharmony_ci        return self._name
11557db96d56Sopenharmony_ci
11567db96d56Sopenharmony_ci    @name.setter
11577db96d56Sopenharmony_ci    def name(self, name):
11587db96d56Sopenharmony_ci        assert self._initialized, "Thread.__init__() not called"
11597db96d56Sopenharmony_ci        self._name = str(name)
11607db96d56Sopenharmony_ci
11617db96d56Sopenharmony_ci    @property
11627db96d56Sopenharmony_ci    def ident(self):
11637db96d56Sopenharmony_ci        """Thread identifier of this thread or None if it has not been started.
11647db96d56Sopenharmony_ci
11657db96d56Sopenharmony_ci        This is a nonzero integer. See the get_ident() function. Thread
11667db96d56Sopenharmony_ci        identifiers may be recycled when a thread exits and another thread is
11677db96d56Sopenharmony_ci        created. The identifier is available even after the thread has exited.
11687db96d56Sopenharmony_ci
11697db96d56Sopenharmony_ci        """
11707db96d56Sopenharmony_ci        assert self._initialized, "Thread.__init__() not called"
11717db96d56Sopenharmony_ci        return self._ident
11727db96d56Sopenharmony_ci
11737db96d56Sopenharmony_ci    if _HAVE_THREAD_NATIVE_ID:
11747db96d56Sopenharmony_ci        @property
11757db96d56Sopenharmony_ci        def native_id(self):
11767db96d56Sopenharmony_ci            """Native integral thread ID of this thread, or None if it has not been started.
11777db96d56Sopenharmony_ci
11787db96d56Sopenharmony_ci            This is a non-negative integer. See the get_native_id() function.
11797db96d56Sopenharmony_ci            This represents the Thread ID as reported by the kernel.
11807db96d56Sopenharmony_ci
11817db96d56Sopenharmony_ci            """
11827db96d56Sopenharmony_ci            assert self._initialized, "Thread.__init__() not called"
11837db96d56Sopenharmony_ci            return self._native_id
11847db96d56Sopenharmony_ci
11857db96d56Sopenharmony_ci    def is_alive(self):
11867db96d56Sopenharmony_ci        """Return whether the thread is alive.
11877db96d56Sopenharmony_ci
11887db96d56Sopenharmony_ci        This method returns True just before the run() method starts until just
11897db96d56Sopenharmony_ci        after the run() method terminates. See also the module function
11907db96d56Sopenharmony_ci        enumerate().
11917db96d56Sopenharmony_ci
11927db96d56Sopenharmony_ci        """
11937db96d56Sopenharmony_ci        assert self._initialized, "Thread.__init__() not called"
11947db96d56Sopenharmony_ci        if self._is_stopped or not self._started.is_set():
11957db96d56Sopenharmony_ci            return False
11967db96d56Sopenharmony_ci        self._wait_for_tstate_lock(False)
11977db96d56Sopenharmony_ci        return not self._is_stopped
11987db96d56Sopenharmony_ci
11997db96d56Sopenharmony_ci    @property
12007db96d56Sopenharmony_ci    def daemon(self):
12017db96d56Sopenharmony_ci        """A boolean value indicating whether this thread is a daemon thread.
12027db96d56Sopenharmony_ci
12037db96d56Sopenharmony_ci        This must be set before start() is called, otherwise RuntimeError is
12047db96d56Sopenharmony_ci        raised. Its initial value is inherited from the creating thread; the
12057db96d56Sopenharmony_ci        main thread is not a daemon thread and therefore all threads created in
12067db96d56Sopenharmony_ci        the main thread default to daemon = False.
12077db96d56Sopenharmony_ci
12087db96d56Sopenharmony_ci        The entire Python program exits when only daemon threads are left.
12097db96d56Sopenharmony_ci
12107db96d56Sopenharmony_ci        """
12117db96d56Sopenharmony_ci        assert self._initialized, "Thread.__init__() not called"
12127db96d56Sopenharmony_ci        return self._daemonic
12137db96d56Sopenharmony_ci
12147db96d56Sopenharmony_ci    @daemon.setter
12157db96d56Sopenharmony_ci    def daemon(self, daemonic):
12167db96d56Sopenharmony_ci        if not self._initialized:
12177db96d56Sopenharmony_ci            raise RuntimeError("Thread.__init__() not called")
12187db96d56Sopenharmony_ci        if self._started.is_set():
12197db96d56Sopenharmony_ci            raise RuntimeError("cannot set daemon status of active thread")
12207db96d56Sopenharmony_ci        self._daemonic = daemonic
12217db96d56Sopenharmony_ci
12227db96d56Sopenharmony_ci    def isDaemon(self):
12237db96d56Sopenharmony_ci        """Return whether this thread is a daemon.
12247db96d56Sopenharmony_ci
12257db96d56Sopenharmony_ci        This method is deprecated, use the daemon attribute instead.
12267db96d56Sopenharmony_ci
12277db96d56Sopenharmony_ci        """
12287db96d56Sopenharmony_ci        import warnings
12297db96d56Sopenharmony_ci        warnings.warn('isDaemon() is deprecated, get the daemon attribute instead',
12307db96d56Sopenharmony_ci                      DeprecationWarning, stacklevel=2)
12317db96d56Sopenharmony_ci        return self.daemon
12327db96d56Sopenharmony_ci
12337db96d56Sopenharmony_ci    def setDaemon(self, daemonic):
12347db96d56Sopenharmony_ci        """Set whether this thread is a daemon.
12357db96d56Sopenharmony_ci
12367db96d56Sopenharmony_ci        This method is deprecated, use the .daemon property instead.
12377db96d56Sopenharmony_ci
12387db96d56Sopenharmony_ci        """
12397db96d56Sopenharmony_ci        import warnings
12407db96d56Sopenharmony_ci        warnings.warn('setDaemon() is deprecated, set the daemon attribute instead',
12417db96d56Sopenharmony_ci                      DeprecationWarning, stacklevel=2)
12427db96d56Sopenharmony_ci        self.daemon = daemonic
12437db96d56Sopenharmony_ci
12447db96d56Sopenharmony_ci    def getName(self):
12457db96d56Sopenharmony_ci        """Return a string used for identification purposes only.
12467db96d56Sopenharmony_ci
12477db96d56Sopenharmony_ci        This method is deprecated, use the name attribute instead.
12487db96d56Sopenharmony_ci
12497db96d56Sopenharmony_ci        """
12507db96d56Sopenharmony_ci        import warnings
12517db96d56Sopenharmony_ci        warnings.warn('getName() is deprecated, get the name attribute instead',
12527db96d56Sopenharmony_ci                      DeprecationWarning, stacklevel=2)
12537db96d56Sopenharmony_ci        return self.name
12547db96d56Sopenharmony_ci
12557db96d56Sopenharmony_ci    def setName(self, name):
12567db96d56Sopenharmony_ci        """Set the name string for this thread.
12577db96d56Sopenharmony_ci
12587db96d56Sopenharmony_ci        This method is deprecated, use the name attribute instead.
12597db96d56Sopenharmony_ci
12607db96d56Sopenharmony_ci        """
12617db96d56Sopenharmony_ci        import warnings
12627db96d56Sopenharmony_ci        warnings.warn('setName() is deprecated, set the name attribute instead',
12637db96d56Sopenharmony_ci                      DeprecationWarning, stacklevel=2)
12647db96d56Sopenharmony_ci        self.name = name
12657db96d56Sopenharmony_ci
12667db96d56Sopenharmony_ci
12677db96d56Sopenharmony_citry:
12687db96d56Sopenharmony_ci    from _thread import (_excepthook as excepthook,
12697db96d56Sopenharmony_ci                         _ExceptHookArgs as ExceptHookArgs)
12707db96d56Sopenharmony_ciexcept ImportError:
12717db96d56Sopenharmony_ci    # Simple Python implementation if _thread._excepthook() is not available
12727db96d56Sopenharmony_ci    from traceback import print_exception as _print_exception
12737db96d56Sopenharmony_ci    from collections import namedtuple
12747db96d56Sopenharmony_ci
12757db96d56Sopenharmony_ci    _ExceptHookArgs = namedtuple(
12767db96d56Sopenharmony_ci        'ExceptHookArgs',
12777db96d56Sopenharmony_ci        'exc_type exc_value exc_traceback thread')
12787db96d56Sopenharmony_ci
12797db96d56Sopenharmony_ci    def ExceptHookArgs(args):
12807db96d56Sopenharmony_ci        return _ExceptHookArgs(*args)
12817db96d56Sopenharmony_ci
12827db96d56Sopenharmony_ci    def excepthook(args, /):
12837db96d56Sopenharmony_ci        """
12847db96d56Sopenharmony_ci        Handle uncaught Thread.run() exception.
12857db96d56Sopenharmony_ci        """
12867db96d56Sopenharmony_ci        if args.exc_type == SystemExit:
12877db96d56Sopenharmony_ci            # silently ignore SystemExit
12887db96d56Sopenharmony_ci            return
12897db96d56Sopenharmony_ci
12907db96d56Sopenharmony_ci        if _sys is not None and _sys.stderr is not None:
12917db96d56Sopenharmony_ci            stderr = _sys.stderr
12927db96d56Sopenharmony_ci        elif args.thread is not None:
12937db96d56Sopenharmony_ci            stderr = args.thread._stderr
12947db96d56Sopenharmony_ci            if stderr is None:
12957db96d56Sopenharmony_ci                # do nothing if sys.stderr is None and sys.stderr was None
12967db96d56Sopenharmony_ci                # when the thread was created
12977db96d56Sopenharmony_ci                return
12987db96d56Sopenharmony_ci        else:
12997db96d56Sopenharmony_ci            # do nothing if sys.stderr is None and args.thread is None
13007db96d56Sopenharmony_ci            return
13017db96d56Sopenharmony_ci
13027db96d56Sopenharmony_ci        if args.thread is not None:
13037db96d56Sopenharmony_ci            name = args.thread.name
13047db96d56Sopenharmony_ci        else:
13057db96d56Sopenharmony_ci            name = get_ident()
13067db96d56Sopenharmony_ci        print(f"Exception in thread {name}:",
13077db96d56Sopenharmony_ci              file=stderr, flush=True)
13087db96d56Sopenharmony_ci        _print_exception(args.exc_type, args.exc_value, args.exc_traceback,
13097db96d56Sopenharmony_ci                         file=stderr)
13107db96d56Sopenharmony_ci        stderr.flush()
13117db96d56Sopenharmony_ci
13127db96d56Sopenharmony_ci
13137db96d56Sopenharmony_ci# Original value of threading.excepthook
13147db96d56Sopenharmony_ci__excepthook__ = excepthook
13157db96d56Sopenharmony_ci
13167db96d56Sopenharmony_ci
13177db96d56Sopenharmony_cidef _make_invoke_excepthook():
13187db96d56Sopenharmony_ci    # Create a local namespace to ensure that variables remain alive
13197db96d56Sopenharmony_ci    # when _invoke_excepthook() is called, even if it is called late during
13207db96d56Sopenharmony_ci    # Python shutdown. It is mostly needed for daemon threads.
13217db96d56Sopenharmony_ci
13227db96d56Sopenharmony_ci    old_excepthook = excepthook
13237db96d56Sopenharmony_ci    old_sys_excepthook = _sys.excepthook
13247db96d56Sopenharmony_ci    if old_excepthook is None:
13257db96d56Sopenharmony_ci        raise RuntimeError("threading.excepthook is None")
13267db96d56Sopenharmony_ci    if old_sys_excepthook is None:
13277db96d56Sopenharmony_ci        raise RuntimeError("sys.excepthook is None")
13287db96d56Sopenharmony_ci
13297db96d56Sopenharmony_ci    sys_exc_info = _sys.exc_info
13307db96d56Sopenharmony_ci    local_print = print
13317db96d56Sopenharmony_ci    local_sys = _sys
13327db96d56Sopenharmony_ci
13337db96d56Sopenharmony_ci    def invoke_excepthook(thread):
13347db96d56Sopenharmony_ci        global excepthook
13357db96d56Sopenharmony_ci        try:
13367db96d56Sopenharmony_ci            hook = excepthook
13377db96d56Sopenharmony_ci            if hook is None:
13387db96d56Sopenharmony_ci                hook = old_excepthook
13397db96d56Sopenharmony_ci
13407db96d56Sopenharmony_ci            args = ExceptHookArgs([*sys_exc_info(), thread])
13417db96d56Sopenharmony_ci
13427db96d56Sopenharmony_ci            hook(args)
13437db96d56Sopenharmony_ci        except Exception as exc:
13447db96d56Sopenharmony_ci            exc.__suppress_context__ = True
13457db96d56Sopenharmony_ci            del exc
13467db96d56Sopenharmony_ci
13477db96d56Sopenharmony_ci            if local_sys is not None and local_sys.stderr is not None:
13487db96d56Sopenharmony_ci                stderr = local_sys.stderr
13497db96d56Sopenharmony_ci            else:
13507db96d56Sopenharmony_ci                stderr = thread._stderr
13517db96d56Sopenharmony_ci
13527db96d56Sopenharmony_ci            local_print("Exception in threading.excepthook:",
13537db96d56Sopenharmony_ci                        file=stderr, flush=True)
13547db96d56Sopenharmony_ci
13557db96d56Sopenharmony_ci            if local_sys is not None and local_sys.excepthook is not None:
13567db96d56Sopenharmony_ci                sys_excepthook = local_sys.excepthook
13577db96d56Sopenharmony_ci            else:
13587db96d56Sopenharmony_ci                sys_excepthook = old_sys_excepthook
13597db96d56Sopenharmony_ci
13607db96d56Sopenharmony_ci            sys_excepthook(*sys_exc_info())
13617db96d56Sopenharmony_ci        finally:
13627db96d56Sopenharmony_ci            # Break reference cycle (exception stored in a variable)
13637db96d56Sopenharmony_ci            args = None
13647db96d56Sopenharmony_ci
13657db96d56Sopenharmony_ci    return invoke_excepthook
13667db96d56Sopenharmony_ci
13677db96d56Sopenharmony_ci
13687db96d56Sopenharmony_ci# The timer class was contributed by Itamar Shtull-Trauring
13697db96d56Sopenharmony_ci
13707db96d56Sopenharmony_ciclass Timer(Thread):
13717db96d56Sopenharmony_ci    """Call a function after a specified number of seconds:
13727db96d56Sopenharmony_ci
13737db96d56Sopenharmony_ci            t = Timer(30.0, f, args=None, kwargs=None)
13747db96d56Sopenharmony_ci            t.start()
13757db96d56Sopenharmony_ci            t.cancel()     # stop the timer's action if it's still waiting
13767db96d56Sopenharmony_ci
13777db96d56Sopenharmony_ci    """
13787db96d56Sopenharmony_ci
13797db96d56Sopenharmony_ci    def __init__(self, interval, function, args=None, kwargs=None):
13807db96d56Sopenharmony_ci        Thread.__init__(self)
13817db96d56Sopenharmony_ci        self.interval = interval
13827db96d56Sopenharmony_ci        self.function = function
13837db96d56Sopenharmony_ci        self.args = args if args is not None else []
13847db96d56Sopenharmony_ci        self.kwargs = kwargs if kwargs is not None else {}
13857db96d56Sopenharmony_ci        self.finished = Event()
13867db96d56Sopenharmony_ci
13877db96d56Sopenharmony_ci    def cancel(self):
13887db96d56Sopenharmony_ci        """Stop the timer if it hasn't finished yet."""
13897db96d56Sopenharmony_ci        self.finished.set()
13907db96d56Sopenharmony_ci
13917db96d56Sopenharmony_ci    def run(self):
13927db96d56Sopenharmony_ci        self.finished.wait(self.interval)
13937db96d56Sopenharmony_ci        if not self.finished.is_set():
13947db96d56Sopenharmony_ci            self.function(*self.args, **self.kwargs)
13957db96d56Sopenharmony_ci        self.finished.set()
13967db96d56Sopenharmony_ci
13977db96d56Sopenharmony_ci
13987db96d56Sopenharmony_ci# Special thread class to represent the main thread
13997db96d56Sopenharmony_ci
14007db96d56Sopenharmony_ciclass _MainThread(Thread):
14017db96d56Sopenharmony_ci
14027db96d56Sopenharmony_ci    def __init__(self):
14037db96d56Sopenharmony_ci        Thread.__init__(self, name="MainThread", daemon=False)
14047db96d56Sopenharmony_ci        self._set_tstate_lock()
14057db96d56Sopenharmony_ci        self._started.set()
14067db96d56Sopenharmony_ci        self._set_ident()
14077db96d56Sopenharmony_ci        if _HAVE_THREAD_NATIVE_ID:
14087db96d56Sopenharmony_ci            self._set_native_id()
14097db96d56Sopenharmony_ci        with _active_limbo_lock:
14107db96d56Sopenharmony_ci            _active[self._ident] = self
14117db96d56Sopenharmony_ci
14127db96d56Sopenharmony_ci
14137db96d56Sopenharmony_ci# Dummy thread class to represent threads not started here.
14147db96d56Sopenharmony_ci# These aren't garbage collected when they die, nor can they be waited for.
14157db96d56Sopenharmony_ci# If they invoke anything in threading.py that calls current_thread(), they
14167db96d56Sopenharmony_ci# leave an entry in the _active dict forever after.
14177db96d56Sopenharmony_ci# Their purpose is to return *something* from current_thread().
14187db96d56Sopenharmony_ci# They are marked as daemon threads so we won't wait for them
14197db96d56Sopenharmony_ci# when we exit (conform previous semantics).
14207db96d56Sopenharmony_ci
14217db96d56Sopenharmony_ciclass _DummyThread(Thread):
14227db96d56Sopenharmony_ci
14237db96d56Sopenharmony_ci    def __init__(self):
14247db96d56Sopenharmony_ci        Thread.__init__(self, name=_newname("Dummy-%d"), daemon=True)
14257db96d56Sopenharmony_ci
14267db96d56Sopenharmony_ci        self._started.set()
14277db96d56Sopenharmony_ci        self._set_ident()
14287db96d56Sopenharmony_ci        if _HAVE_THREAD_NATIVE_ID:
14297db96d56Sopenharmony_ci            self._set_native_id()
14307db96d56Sopenharmony_ci        with _active_limbo_lock:
14317db96d56Sopenharmony_ci            _active[self._ident] = self
14327db96d56Sopenharmony_ci
14337db96d56Sopenharmony_ci    def _stop(self):
14347db96d56Sopenharmony_ci        pass
14357db96d56Sopenharmony_ci
14367db96d56Sopenharmony_ci    def is_alive(self):
14377db96d56Sopenharmony_ci        assert not self._is_stopped and self._started.is_set()
14387db96d56Sopenharmony_ci        return True
14397db96d56Sopenharmony_ci
14407db96d56Sopenharmony_ci    def join(self, timeout=None):
14417db96d56Sopenharmony_ci        assert False, "cannot join a dummy thread"
14427db96d56Sopenharmony_ci
14437db96d56Sopenharmony_ci
14447db96d56Sopenharmony_ci# Global API functions
14457db96d56Sopenharmony_ci
14467db96d56Sopenharmony_cidef current_thread():
14477db96d56Sopenharmony_ci    """Return the current Thread object, corresponding to the caller's thread of control.
14487db96d56Sopenharmony_ci
14497db96d56Sopenharmony_ci    If the caller's thread of control was not created through the threading
14507db96d56Sopenharmony_ci    module, a dummy thread object with limited functionality is returned.
14517db96d56Sopenharmony_ci
14527db96d56Sopenharmony_ci    """
14537db96d56Sopenharmony_ci    try:
14547db96d56Sopenharmony_ci        return _active[get_ident()]
14557db96d56Sopenharmony_ci    except KeyError:
14567db96d56Sopenharmony_ci        return _DummyThread()
14577db96d56Sopenharmony_ci
14587db96d56Sopenharmony_cidef currentThread():
14597db96d56Sopenharmony_ci    """Return the current Thread object, corresponding to the caller's thread of control.
14607db96d56Sopenharmony_ci
14617db96d56Sopenharmony_ci    This function is deprecated, use current_thread() instead.
14627db96d56Sopenharmony_ci
14637db96d56Sopenharmony_ci    """
14647db96d56Sopenharmony_ci    import warnings
14657db96d56Sopenharmony_ci    warnings.warn('currentThread() is deprecated, use current_thread() instead',
14667db96d56Sopenharmony_ci                  DeprecationWarning, stacklevel=2)
14677db96d56Sopenharmony_ci    return current_thread()
14687db96d56Sopenharmony_ci
14697db96d56Sopenharmony_cidef active_count():
14707db96d56Sopenharmony_ci    """Return the number of Thread objects currently alive.
14717db96d56Sopenharmony_ci
14727db96d56Sopenharmony_ci    The returned count is equal to the length of the list returned by
14737db96d56Sopenharmony_ci    enumerate().
14747db96d56Sopenharmony_ci
14757db96d56Sopenharmony_ci    """
14767db96d56Sopenharmony_ci    with _active_limbo_lock:
14777db96d56Sopenharmony_ci        return len(_active) + len(_limbo)
14787db96d56Sopenharmony_ci
14797db96d56Sopenharmony_cidef activeCount():
14807db96d56Sopenharmony_ci    """Return the number of Thread objects currently alive.
14817db96d56Sopenharmony_ci
14827db96d56Sopenharmony_ci    This function is deprecated, use active_count() instead.
14837db96d56Sopenharmony_ci
14847db96d56Sopenharmony_ci    """
14857db96d56Sopenharmony_ci    import warnings
14867db96d56Sopenharmony_ci    warnings.warn('activeCount() is deprecated, use active_count() instead',
14877db96d56Sopenharmony_ci                  DeprecationWarning, stacklevel=2)
14887db96d56Sopenharmony_ci    return active_count()
14897db96d56Sopenharmony_ci
14907db96d56Sopenharmony_cidef _enumerate():
14917db96d56Sopenharmony_ci    # Same as enumerate(), but without the lock. Internal use only.
14927db96d56Sopenharmony_ci    return list(_active.values()) + list(_limbo.values())
14937db96d56Sopenharmony_ci
14947db96d56Sopenharmony_cidef enumerate():
14957db96d56Sopenharmony_ci    """Return a list of all Thread objects currently alive.
14967db96d56Sopenharmony_ci
14977db96d56Sopenharmony_ci    The list includes daemonic threads, dummy thread objects created by
14987db96d56Sopenharmony_ci    current_thread(), and the main thread. It excludes terminated threads and
14997db96d56Sopenharmony_ci    threads that have not yet been started.
15007db96d56Sopenharmony_ci
15017db96d56Sopenharmony_ci    """
15027db96d56Sopenharmony_ci    with _active_limbo_lock:
15037db96d56Sopenharmony_ci        return list(_active.values()) + list(_limbo.values())
15047db96d56Sopenharmony_ci
15057db96d56Sopenharmony_ci
15067db96d56Sopenharmony_ci_threading_atexits = []
15077db96d56Sopenharmony_ci_SHUTTING_DOWN = False
15087db96d56Sopenharmony_ci
15097db96d56Sopenharmony_cidef _register_atexit(func, *arg, **kwargs):
15107db96d56Sopenharmony_ci    """CPython internal: register *func* to be called before joining threads.
15117db96d56Sopenharmony_ci
15127db96d56Sopenharmony_ci    The registered *func* is called with its arguments just before all
15137db96d56Sopenharmony_ci    non-daemon threads are joined in `_shutdown()`. It provides a similar
15147db96d56Sopenharmony_ci    purpose to `atexit.register()`, but its functions are called prior to
15157db96d56Sopenharmony_ci    threading shutdown instead of interpreter shutdown.
15167db96d56Sopenharmony_ci
15177db96d56Sopenharmony_ci    For similarity to atexit, the registered functions are called in reverse.
15187db96d56Sopenharmony_ci    """
15197db96d56Sopenharmony_ci    if _SHUTTING_DOWN:
15207db96d56Sopenharmony_ci        raise RuntimeError("can't register atexit after shutdown")
15217db96d56Sopenharmony_ci
15227db96d56Sopenharmony_ci    call = functools.partial(func, *arg, **kwargs)
15237db96d56Sopenharmony_ci    _threading_atexits.append(call)
15247db96d56Sopenharmony_ci
15257db96d56Sopenharmony_ci
15267db96d56Sopenharmony_cifrom _thread import stack_size
15277db96d56Sopenharmony_ci
15287db96d56Sopenharmony_ci# Create the main thread object,
15297db96d56Sopenharmony_ci# and make it available for the interpreter
15307db96d56Sopenharmony_ci# (Py_Main) as threading._shutdown.
15317db96d56Sopenharmony_ci
15327db96d56Sopenharmony_ci_main_thread = _MainThread()
15337db96d56Sopenharmony_ci
15347db96d56Sopenharmony_cidef _shutdown():
15357db96d56Sopenharmony_ci    """
15367db96d56Sopenharmony_ci    Wait until the Python thread state of all non-daemon threads get deleted.
15377db96d56Sopenharmony_ci    """
15387db96d56Sopenharmony_ci    # Obscure:  other threads may be waiting to join _main_thread.  That's
15397db96d56Sopenharmony_ci    # dubious, but some code does it.  We can't wait for C code to release
15407db96d56Sopenharmony_ci    # the main thread's tstate_lock - that won't happen until the interpreter
15417db96d56Sopenharmony_ci    # is nearly dead.  So we release it here.  Note that just calling _stop()
15427db96d56Sopenharmony_ci    # isn't enough:  other threads may already be waiting on _tstate_lock.
15437db96d56Sopenharmony_ci    if _main_thread._is_stopped:
15447db96d56Sopenharmony_ci        # _shutdown() was already called
15457db96d56Sopenharmony_ci        return
15467db96d56Sopenharmony_ci
15477db96d56Sopenharmony_ci    global _SHUTTING_DOWN
15487db96d56Sopenharmony_ci    _SHUTTING_DOWN = True
15497db96d56Sopenharmony_ci
15507db96d56Sopenharmony_ci    # Call registered threading atexit functions before threads are joined.
15517db96d56Sopenharmony_ci    # Order is reversed, similar to atexit.
15527db96d56Sopenharmony_ci    for atexit_call in reversed(_threading_atexits):
15537db96d56Sopenharmony_ci        atexit_call()
15547db96d56Sopenharmony_ci
15557db96d56Sopenharmony_ci    # Main thread
15567db96d56Sopenharmony_ci    if _main_thread.ident == get_ident():
15577db96d56Sopenharmony_ci        tlock = _main_thread._tstate_lock
15587db96d56Sopenharmony_ci        # The main thread isn't finished yet, so its thread state lock can't
15597db96d56Sopenharmony_ci        # have been released.
15607db96d56Sopenharmony_ci        assert tlock is not None
15617db96d56Sopenharmony_ci        assert tlock.locked()
15627db96d56Sopenharmony_ci        tlock.release()
15637db96d56Sopenharmony_ci        _main_thread._stop()
15647db96d56Sopenharmony_ci    else:
15657db96d56Sopenharmony_ci        # bpo-1596321: _shutdown() must be called in the main thread.
15667db96d56Sopenharmony_ci        # If the threading module was not imported by the main thread,
15677db96d56Sopenharmony_ci        # _main_thread is the thread which imported the threading module.
15687db96d56Sopenharmony_ci        # In this case, ignore _main_thread, similar behavior than for threads
15697db96d56Sopenharmony_ci        # spawned by C libraries or using _thread.start_new_thread().
15707db96d56Sopenharmony_ci        pass
15717db96d56Sopenharmony_ci
15727db96d56Sopenharmony_ci    # Join all non-deamon threads
15737db96d56Sopenharmony_ci    while True:
15747db96d56Sopenharmony_ci        with _shutdown_locks_lock:
15757db96d56Sopenharmony_ci            locks = list(_shutdown_locks)
15767db96d56Sopenharmony_ci            _shutdown_locks.clear()
15777db96d56Sopenharmony_ci
15787db96d56Sopenharmony_ci        if not locks:
15797db96d56Sopenharmony_ci            break
15807db96d56Sopenharmony_ci
15817db96d56Sopenharmony_ci        for lock in locks:
15827db96d56Sopenharmony_ci            # mimic Thread.join()
15837db96d56Sopenharmony_ci            lock.acquire()
15847db96d56Sopenharmony_ci            lock.release()
15857db96d56Sopenharmony_ci
15867db96d56Sopenharmony_ci        # new threads can be spawned while we were waiting for the other
15877db96d56Sopenharmony_ci        # threads to complete
15887db96d56Sopenharmony_ci
15897db96d56Sopenharmony_ci
15907db96d56Sopenharmony_cidef main_thread():
15917db96d56Sopenharmony_ci    """Return the main thread object.
15927db96d56Sopenharmony_ci
15937db96d56Sopenharmony_ci    In normal conditions, the main thread is the thread from which the
15947db96d56Sopenharmony_ci    Python interpreter was started.
15957db96d56Sopenharmony_ci    """
15967db96d56Sopenharmony_ci    return _main_thread
15977db96d56Sopenharmony_ci
15987db96d56Sopenharmony_ci# get thread-local implementation, either from the thread
15997db96d56Sopenharmony_ci# module, or from the python fallback
16007db96d56Sopenharmony_ci
16017db96d56Sopenharmony_citry:
16027db96d56Sopenharmony_ci    from _thread import _local as local
16037db96d56Sopenharmony_ciexcept ImportError:
16047db96d56Sopenharmony_ci    from _threading_local import local
16057db96d56Sopenharmony_ci
16067db96d56Sopenharmony_ci
16077db96d56Sopenharmony_cidef _after_fork():
16087db96d56Sopenharmony_ci    """
16097db96d56Sopenharmony_ci    Cleanup threading module state that should not exist after a fork.
16107db96d56Sopenharmony_ci    """
16117db96d56Sopenharmony_ci    # Reset _active_limbo_lock, in case we forked while the lock was held
16127db96d56Sopenharmony_ci    # by another (non-forked) thread.  http://bugs.python.org/issue874900
16137db96d56Sopenharmony_ci    global _active_limbo_lock, _main_thread
16147db96d56Sopenharmony_ci    global _shutdown_locks_lock, _shutdown_locks
16157db96d56Sopenharmony_ci    _active_limbo_lock = RLock()
16167db96d56Sopenharmony_ci
16177db96d56Sopenharmony_ci    # fork() only copied the current thread; clear references to others.
16187db96d56Sopenharmony_ci    new_active = {}
16197db96d56Sopenharmony_ci
16207db96d56Sopenharmony_ci    try:
16217db96d56Sopenharmony_ci        current = _active[get_ident()]
16227db96d56Sopenharmony_ci    except KeyError:
16237db96d56Sopenharmony_ci        # fork() was called in a thread which was not spawned
16247db96d56Sopenharmony_ci        # by threading.Thread. For example, a thread spawned
16257db96d56Sopenharmony_ci        # by thread.start_new_thread().
16267db96d56Sopenharmony_ci        current = _MainThread()
16277db96d56Sopenharmony_ci
16287db96d56Sopenharmony_ci    _main_thread = current
16297db96d56Sopenharmony_ci
16307db96d56Sopenharmony_ci    # reset _shutdown() locks: threads re-register their _tstate_lock below
16317db96d56Sopenharmony_ci    _shutdown_locks_lock = _allocate_lock()
16327db96d56Sopenharmony_ci    _shutdown_locks = set()
16337db96d56Sopenharmony_ci
16347db96d56Sopenharmony_ci    with _active_limbo_lock:
16357db96d56Sopenharmony_ci        # Dangling thread instances must still have their locks reset,
16367db96d56Sopenharmony_ci        # because someone may join() them.
16377db96d56Sopenharmony_ci        threads = set(_enumerate())
16387db96d56Sopenharmony_ci        threads.update(_dangling)
16397db96d56Sopenharmony_ci        for thread in threads:
16407db96d56Sopenharmony_ci            # Any lock/condition variable may be currently locked or in an
16417db96d56Sopenharmony_ci            # invalid state, so we reinitialize them.
16427db96d56Sopenharmony_ci            if thread is current:
16437db96d56Sopenharmony_ci                # There is only one active thread. We reset the ident to
16447db96d56Sopenharmony_ci                # its new value since it can have changed.
16457db96d56Sopenharmony_ci                thread._reset_internal_locks(True)
16467db96d56Sopenharmony_ci                ident = get_ident()
16477db96d56Sopenharmony_ci                thread._ident = ident
16487db96d56Sopenharmony_ci                new_active[ident] = thread
16497db96d56Sopenharmony_ci            else:
16507db96d56Sopenharmony_ci                # All the others are already stopped.
16517db96d56Sopenharmony_ci                thread._reset_internal_locks(False)
16527db96d56Sopenharmony_ci                thread._stop()
16537db96d56Sopenharmony_ci
16547db96d56Sopenharmony_ci        _limbo.clear()
16557db96d56Sopenharmony_ci        _active.clear()
16567db96d56Sopenharmony_ci        _active.update(new_active)
16577db96d56Sopenharmony_ci        assert len(_active) == 1
16587db96d56Sopenharmony_ci
16597db96d56Sopenharmony_ci
16607db96d56Sopenharmony_ciif hasattr(_os, "register_at_fork"):
16617db96d56Sopenharmony_ci    _os.register_at_fork(after_in_child=_after_fork)
1662