BYPASS SHELL BY ./RAZORGANZ
Server: nginx/1.20.1
System: Linux iZdzfnv9mwfppeZ 5.10.134-19.2.al8.x86_64 #1 SMP Wed Oct 29 22:47:09 CST 2025 x86_64
User: apache (48)
PHP: 8.2.30
Disabled: NONE
Upload Files
File: //lib64/python3.6/site-packages/tornado/__pycache__/locks.cpython-36.opt-1.pyc
3

	��f�D�@sddlZddlmZddlZddlZddlmZmZddlm	Z	m
Z
ddlmZm
Z
mZmZmZddlZejr~ddlmZmZddd	d
dgZGdd
�d
e�ZGdd�de�ZGdd�de�ZGdd�de�ZGdd	�d	e�ZGdd
�d
e�ZGdd�de�ZdS)�N)�CancelledError)�gen�ioloop)�Future�"future_set_result_unless_cancelled)�Union�Optional�Type�Any�	Awaitable)�Deque�Set�	Condition�Event�	Semaphore�BoundedSemaphore�Lockc@s,eZdZdZdd�dd�Zdd�dd�ZdS)�_TimeoutGarbageCollectorz�Base class for objects that periodically clean up timed-out waiters.

    Avoids memory leak in a common pattern like:

        while True:
            yield condition.wait(short_timeout)
            print('looping....')
    N)�returncCstj�|_d|_dS)Nr)�collections�deque�_waiters�	_timeouts)�self�r�/usr/lib64/python3.6/locks.py�__init__*s
z!_TimeoutGarbageCollector.__init__cCs:|jd7_|jdkr6d|_tjdd�|jD��|_dS)N��drcss|]}|j�s|VqdS)N)�done)�.0�wrrr�	<genexpr>3sz<_TimeoutGarbageCollector._garbage_collect.<locals>.<genexpr>)rrrr)rrrr�_garbage_collect.s
z)_TimeoutGarbageCollector._garbage_collect)�__name__�
__module__�__qualname__�__doc__rr#rrrrr srcsteZdZdZdd��fdd�Zed�dd�Zdeee	j
feed�d	d
�Z
dedd�d
d�Zdd�dd�Z�ZS)ra�A condition allows one or more coroutines to wait until notified.

    Like a standard `threading.Condition`, but does not need an underlying lock
    that is acquired and released.

    With a `Condition`, coroutines can wait to be notified by other coroutines:

    .. testcode::

        from tornado import gen
        from tornado.ioloop import IOLoop
        from tornado.locks import Condition

        condition = Condition()

        async def waiter():
            print("I'll wait right here")
            await condition.wait()
            print("I'm done waiting")

        async def notifier():
            print("About to notify")
            condition.notify()
            print("Done notifying")

        async def runner():
            # Wait for waiter() and notifier() in parallel
            await gen.multi([waiter(), notifier()])

        IOLoop.current().run_sync(runner)

    .. testoutput::

        I'll wait right here
        About to notify
        Done notifying
        I'm done waiting

    `wait` takes an optional ``timeout`` argument, which is either an absolute
    timestamp::

        io_loop = IOLoop.current()

        # Wait up to 1 second for a notification.
        await condition.wait(timeout=io_loop.time() + 1)

    ...or a `datetime.timedelta` for a timeout relative to the current time::

        # Wait up to 1 second.
        await condition.wait(timeout=datetime.timedelta(seconds=1))

    The method returns False if there's no notification before the deadline.

    .. versionchanged:: 5.0
       Previously, waiters could be notified synchronously from within
       `notify`. Now, the notification will always be received on the
       next iteration of the `.IOLoop`.
    N)rcstt|�j�tjj�|_dS)N)�superrrr�IOLoop�current�io_loop)r)�	__class__rrrrszCondition.__init__cCs.d|jjf}|jr&|dt|j�7}|dS)Nz<%sz waiters[%s]�>)r,r$r�len)r�resultrrr�__repr__vszCondition.__repr__)�timeoutrcsXt���jj��|rTdd���fdd�}tjj���j||���j��fdd���S)z�Wait for `.notify`.

        Returns a `.Future` that resolves ``True`` if the condition is notified,
        or ``False`` after a timeout.
        N)rcs�j�st�d��j�dS)NF)rrr#r)r�waiterrr�
on_timeout�s
z"Condition.wait.<locals>.on_timeoutcs
�j��S)N)�remove_timeout)�_)r+�timeout_handlerr�<lambda>�sz Condition.wait.<locals>.<lambda>)rr�appendrr)r*�add_timeout�add_done_callback)rr1r3r)r+rr6r2r�wait|s
zCondition.waitr)�nrcCsTg}x2|r6|jr6|jj�}|j�s|d8}|j|�qWx|D]}t|d�q>WdS)zWake ``n`` waiters.rTN)r�popleftrr8r)rr<�waitersr2rrr�notify�s

zCondition.notifycCs|jt|j��dS)zWake all waiters.N)r?r.r)rrrr�
notify_all�szCondition.notify_all)N)r)r$r%r&r'r�strr0r�float�datetime�	timedeltar�boolr;�intr?r@�
__classcell__rr)r,rr6s: c@sveZdZdZdd�dd�Zed�dd�Zed�dd	�Zdd�d
d�Z	dd�dd
�Z
deee
jfedd�dd�ZdS)ra�An event blocks coroutines until its internal flag is set to True.

    Similar to `threading.Event`.

    A coroutine can wait for an event to be set. Once it is set, calls to
    ``yield event.wait()`` will not block unless the event has been cleared:

    .. testcode::

        from tornado import gen
        from tornado.ioloop import IOLoop
        from tornado.locks import Event

        event = Event()

        async def waiter():
            print("Waiting for event")
            await event.wait()
            print("Not waiting this time")
            await event.wait()
            print("Done")

        async def setter():
            print("About to set the event")
            event.set()

        async def runner():
            await gen.multi([waiter(), setter()])

        IOLoop.current().run_sync(runner)

    .. testoutput::

        Waiting for event
        About to set the event
        Not waiting this time
        Done
    N)rcCsd|_t�|_dS)NF)�_value�setr)rrrrr�szEvent.__init__cCsd|jj|j�rdndfS)Nz<%s %s>rI�clear)r,r$�is_set)rrrrr0�szEvent.__repr__cCs|jS)z-Return ``True`` if the internal flag is true.)rH)rrrrrK�szEvent.is_setcCs2|js.d|_x |jD]}|j�s|jd�qWdS)z�Set the internal flag to ``True``. All waiters are awakened.

        Calling `.wait` once the flag is set will not block.
        TN)rHrr�
set_result)r�futrrrrI�s
z	Event.setcCs
d|_dS)zkReset the internal flag to ``False``.

        Calls to `.wait` will block until `.set` is called.
        FN)rH)rrrrrJ�szEvent.clear)r1rcspt���jr�jd��S�jj���j�fdd��|dkrD�Stj|�tfd�}|j�fdd��|SdS)z�Block until the internal flag is true.

        Returns an awaitable, which raises `tornado.util.TimeoutError` after a
        timeout.
        Ncs�jj|�S)N)r�remove)rM)rrrr7�szEvent.wait.<locals>.<lambda>)Zquiet_exceptionscs�j�s�j�SdS)N)rZcancel)Ztf)rMrrr7s)	rrHrLr�addr:rZwith_timeoutr)rr1Ztimeout_futr)rMrrr;�s
z
Event.wait)N)r$r%r&r'rrAr0rErKrIrJrrBrCrDrr;rrrrr�s&c@sLeZdZdZedd�dd�Zdd�dd�Zd	eeee	j
dd
�dd�ZdS)
�_ReleasingContextManagerz�Releases a Lock or Semaphore at the end of a "with" statement.

        with (yield semaphore.acquire()):
            pass

        # Now semaphore.release() has been called.
    N)�objrcCs
||_dS)N)�_obj)rrQrrrrsz!_ReleasingContextManager.__init__)rcCsdS)Nr)rrrr�	__enter__sz"_ReleasingContextManager.__enter__zOptional[Type[BaseException]])�exc_type�exc_val�exc_tbrcCs|jj�dS)N)rR�release)rrTrUrVrrr�__exit__sz!_ReleasingContextManager.__exit__)r$r%r&r'r
rrSr�
BaseException�types�
TracebackTyperXrrrrrPsrPcs�eZdZdZdedd��fdd�
Zed��fdd	�Zdd�d
d�Zde	e
ejfe
ed�d
d�Zdd�dd�Zdeeeejdd�dd�Zdd�dd�Zdeeeejdd�dd�Z�ZS)raSA lock that can be acquired a fixed number of times before blocking.

    A Semaphore manages a counter representing the number of `.release` calls
    minus the number of `.acquire` calls, plus an initial value. The `.acquire`
    method blocks if necessary until it can return without making the counter
    negative.

    Semaphores limit access to a shared resource. To allow access for two
    workers at a time:

    .. testsetup:: semaphore

       from collections import deque

       from tornado import gen
       from tornado.ioloop import IOLoop
       from tornado.concurrent import Future

       # Ensure reliable doctest output: resolve Futures one at a time.
       futures_q = deque([Future() for _ in range(3)])

       async def simulator(futures):
           for f in futures:
               # simulate the asynchronous passage of time
               await gen.sleep(0)
               await gen.sleep(0)
               f.set_result(None)

       IOLoop.current().add_callback(simulator, list(futures_q))

       def use_some_resource():
           return futures_q.popleft()

    .. testcode:: semaphore

        from tornado import gen
        from tornado.ioloop import IOLoop
        from tornado.locks import Semaphore

        sem = Semaphore(2)

        async def worker(worker_id):
            await sem.acquire()
            try:
                print("Worker %d is working" % worker_id)
                await use_some_resource()
            finally:
                print("Worker %d is done" % worker_id)
                sem.release()

        async def runner():
            # Join all workers.
            await gen.multi([worker(i) for i in range(3)])

        IOLoop.current().run_sync(runner)

    .. testoutput:: semaphore

        Worker 0 is working
        Worker 1 is working
        Worker 0 is done
        Worker 2 is working
        Worker 1 is done
        Worker 2 is done

    Workers 0 and 1 are allowed to run concurrently, but worker 2 waits until
    the semaphore has been released once, by worker 0.

    The semaphore can be used as an async context manager::

        async def worker(worker_id):
            async with sem:
                print("Worker %d is working" % worker_id)
                await use_some_resource()

            # Now the semaphore has been released.
            print("Worker %d is done" % worker_id)

    For compatibility with older versions of Python, `.acquire` is a
    context manager, so ``worker`` could also be written as::

        @gen.coroutine
        def worker(worker_id):
            with (yield sem.acquire()):
                print("Worker %d is working" % worker_id)
                yield use_some_resource()

            # Now the semaphore has been released.
            print("Worker %d is done" % worker_id)

    .. versionchanged:: 4.3
       Added ``async with`` support in Python 3.5.

    rN)�valuercs(tt|�j�|dkrtd��||_dS)Nrz$semaphore initial value must be >= 0)r(rr�
ValueErrorrH)rr\)r,rrr}szSemaphore.__init__)rcsTtt|�j�}|jdkrdn
dj|j�}|jr@dj|t|j��}dj|dd�|�S)Nr�lockedzunlocked,value:{0}z{0},waiters:{1}z<{0} [{1}]>r���)r(rr0rH�formatrr.)r�resZextra)r,rrr0�s
zSemaphore.__repr__cCsN|jd7_x:|jrH|jj�}|j�s|jd8_|jt|��PqWdS)z*Increment the counter and wake one waiter.rN)rHrr=rrLrP)rr2rrrrW�s
zSemaphore.release)r1rcs�t���jdkr.�jd8_�jt���nN�jj��|r|dd���fdd�}tjj���j	||���j
��fdd���S)	z�Decrement the counter. Returns an awaitable.

        Block if the counter is zero and wait for a `.release`. The awaitable
        raises `.TimeoutError` after the deadline.
        rrN)rcs"�j�s�jtj���j�dS)N)rZ
set_exceptionr�TimeoutErrorr#r)rr2rrr3�sz%Semaphore.acquire.<locals>.on_timeoutcs
�j��S)N)r4)r5)r+r6rrr7�sz#Semaphore.acquire.<locals>.<lambda>)rrHrLrPrr8rr)r*r9r:)rr1r3r)r+rr6r2r�acquire�s

zSemaphore.acquirecCstd��dS)Nz0Use 'async with' instead of 'with' for Semaphore)�RuntimeError)rrrrrS�szSemaphore.__enter__zOptional[Type[BaseException]])�typr\�	tracebackrcCs|j�dS)N)rS)rrer\rfrrrrX�szSemaphore.__exit__c�s|j�IdHdS)N)rc)rrrr�
__aenter__�szSemaphore.__aenter__)rer\�tbrc�s|j�dS)N)rW)rrer\rhrrr�	__aexit__�szSemaphore.__aexit__)r)N)r$r%r&r'rFrrAr0rWrrBrCrDrrPrcrSrrYrZr[rXrgrirGrr)r,rrs ^	cs<eZdZdZd
edd��fdd�
Zdd��fdd	�Z�ZS)ra:A semaphore that prevents release() being called too many times.

    If `.release` would increment the semaphore's value past the initial
    value, it raises `ValueError`. Semaphores are mostly used to guard
    resources with limited capacity, so a semaphore released too many times
    is a sign of a bug.
    rN)r\rcstt|�j|d�||_dS)N)r\)r(rr�_initial_value)rr\)r,rrr�szBoundedSemaphore.__init__)rcs&|j|jkrtd��tt|�j�dS)z*Increment the counter and wake one waiter.z!Semaphore released too many timesN)rHrjr]r(rrW)r)r,rrrW�szBoundedSemaphore.release)r)r$r%r&r'rFrrWrGrr)r,rr�sc@s�eZdZdZdd�dd�Zed�dd�Zdeee	j
feed�d	d
�Z
dd�dd�Zdd�d
d�Zdeeeejdd�dd�Zdd�dd�Zdeeeejdd�dd�ZdS)ra�A lock for coroutines.

    A Lock begins unlocked, and `acquire` locks it immediately. While it is
    locked, a coroutine that yields `acquire` waits until another coroutine
    calls `release`.

    Releasing an unlocked lock raises `RuntimeError`.

    A Lock can be used as an async context manager with the ``async
    with`` statement:

    >>> from tornado import locks
    >>> lock = locks.Lock()
    >>>
    >>> async def f():
    ...    async with lock:
    ...        # Do something holding the lock.
    ...        pass
    ...
    ...    # Now the lock is released.

    For compatibility with older versions of Python, the `.acquire`
    method asynchronously returns a regular context manager:

    >>> async def f2():
    ...    with (yield lock.acquire()):
    ...        # Do something holding the lock.
    ...        pass
    ...
    ...    # Now the lock is released.

    .. versionchanged:: 4.3
       Added ``async with`` support in Python 3.5.

    N)rcCstdd�|_dS)Nr)r\)r�_block)rrrrr
sz
Lock.__init__cCsd|jj|jfS)Nz<%s _block=%s>)r,r$rk)rrrrr0
sz
Lock.__repr__)r1rcCs|jj|�S)z�Attempt to lock. Returns an awaitable.

        Returns an awaitable, which raises `tornado.util.TimeoutError` after a
        timeout.
        )rkrc)rr1rrrrcszLock.acquirecCs0y|jj�Wntk
r*td��YnXdS)z�Unlock.

        The first coroutine in line waiting for `acquire` gets the lock.

        If not locked, raise a `RuntimeError`.
        zrelease unlocked lockN)rkrWr]rd)rrrrrWszLock.releasecCstd��dS)Nz+Use `async with` instead of `with` for Lock)rd)rrrrrS&szLock.__enter__zOptional[Type[BaseException]])rer\rhrcCs|j�dS)N)rS)rrer\rhrrrrX)sz
Lock.__exit__c�s|j�IdHdS)N)rc)rrrrrg1szLock.__aenter__c�s|j�dS)N)rW)rrer\rhrrrri4szLock.__aexit__)N)r$r%r&r'rrAr0rrBrCrDrrPrcrWrSrrYrZr[rXrgrirrrrr�s #)r�concurrent.futuresrrCrZZtornadorrZtornado.concurrentrrZtypingrrr	r
rZ
TYPE_CHECKINGrr
�__all__�objectrrrrPrrrrrrr�<module>s$kd5