
    <|h                        d Z ddlmZ ddlmZ ddlmZ ddlZddlmZ ddl	m
Z
 dgZ e       Z ed	      j                   e       d
<   d  e       d<    G d de      Z G d de      Zd Z e        ddlmZ  e e       d       y)z 
Low-level waiting primitives.

    )absolute_import)division)print_functionN)get_hub_noargs)ConcurrentObjectUseErrorWaitergreenlet
getcurrentc                       y N r       M/var/www/html/test/engine/venv/lib/python3.12/site-packages/gevent/_waiter.py<lambda>r      s    r   greenlet_initc                   f    e Zd ZdZg dZddZd Zd Zd Zd Z	e
d	        Zd
 Zd Zd Zd Zd Zy)r   a:  
    A low level communication utility for greenlets.

    Waiter is a wrapper around greenlet's ``switch()`` and ``throw()`` calls that makes them somewhat safer:

    * switching will occur only if the waiting greenlet is executing :meth:`get` method currently;
    * any error raised in the greenlet is handled inside :meth:`switch` and :meth:`throw`
    * if :meth:`switch`/:meth:`throw` is called before the receiver calls :meth:`get`, then :class:`Waiter`
      will store the value/exception. The following :meth:`get` will return the value/raise the exception.

    The :meth:`switch` and :meth:`throw` methods must only be called from the :class:`Hub` greenlet.
    The :meth:`get` method must be called from a greenlet other than :class:`Hub`.

        >>> from gevent.hub import Waiter
        >>> from gevent import get_hub
        >>> result = Waiter()
        >>> timer = get_hub().loop.timer(0.1)
        >>> timer.start(result.switch, 'hello from Waiter')
        >>> result.get() # blocks for 0.1 seconds
        'hello from Waiter'
        >>> timer.close()

    If switch is called before the greenlet gets a chance to call :meth:`get` then
    :class:`Waiter` stores the value.

        >>> from gevent.time import sleep
        >>> result = Waiter()
        >>> timer = get_hub().loop.timer(0.1)
        >>> timer.start(result.switch, 'hi from Waiter')
        >>> sleep(0.2)
        >>> result.get() # returns immediately without blocking
        'hi from Waiter'
        >>> timer.close()

    .. warning::

        This is a limited and dangerous way to communicate between
        greenlets. It can easily leave a greenlet unscheduled forever
        if used incorrectly. Consider using safer classes such as
        :class:`gevent.event.Event`, :class:`gevent.event.AsyncResult`,
        or :class:`gevent.queue.Queue`.
    )hubr	   value
_exceptionNc                 \    |
t               n|| _        d | _        d | _        t        | _        y r   )get_hubr   r	   r   _NONEr   selfr   s     r   __init__zWaiter.__init__I   s&     #79
r   c                 6    d | _         d | _        t        | _        y r   )r	   r   r   r   r   s    r   clearzWaiter.clearO   s    
r   c                 V   | j                   t        u r&dt        |       j                  d| j                  dS | j                   3dt        |       j                  d| j                  d| j
                  dS dt        |       j                  d| j                  d| j                  dS )N<z
 greenlet=>z value=z
 exc_info=)r   r   type__name__r	   r   exc_infor   s    r   __str__zWaiter.__str__T   sz    ??e#)-d)<)<dmmLL??"26t*2E2Et}}VZV`V`aa #15d1D1DdmmUYUbUbccr   c                 &    | j                   t        uS )z;Return true if and only if it holds a value or an exceptionr   r   r   s    r   readyzWaiter.ready[   s    e++r   c                     | j                   du S )z8Return true if and only if it is ready and holds a valueN)r   r   s    r   
successfulzWaiter.successful_   s    $&&r   c                 @    | j                   t        ur| j                   S y)zaHolds the exception info passed to :meth:`throw` if :meth:`throw` was called. Otherwise ``None``.Nr'   r   s    r   r$   zWaiter.exc_infoc   s     ??%'??" (r   c                    | j                   }||| _        d| _        yt               | j                  urt        d      |j                  }	  ||       y#   | j                  j                  |gt        j                           Y yxY w)z
        Switch to the greenlet if one's available. Otherwise store the
        *value*.

        .. versionchanged:: 1.3b1
           The *value* is no longer optional.
        N7Can only use Waiter.switch method from the Hub greenlet)
r	   r   r   r
   r   AssertionErrorswitchhandle_errorsysr$   )r   r   r	   r/   s       r   r/   zWaiter.switchi   sv     ==DJ"DO|488+$%^____F?u?%%%f>s||~>s   A 1Bc                 $    | j                  |      S r   )r/   )r   argss     r   switch_argszWaiter.switch_args~   s    {{4  r   c                    | j                   }||| _        yt               | j                  urt	        d      |j
                  }	  ||  y#   | j                  j                  |gt        j                           Y yxY w)zWSwitch to the greenlet with the exception. If there's no greenlet, store the exception.Nr-   )	r	   r   r
   r   r.   throwr0   r1   r$   )r   
throw_argsr	   r6   s       r   r6   zWaiter.throw   sn    ==(DO|488+$%^__NNE>z">%%%e=clln=s   A 1A>c                 \   | j                   t        ur:| j                   | j                  S  t               j                  | j                     y| j
                  t        d| j
                        t               | _        	 | j                  j                         d| _        S # d| _        w xY w)zbIf a value/an exception is stored, return/raise it. Otherwise until switch() or throw() is called.NzThis Waiter is already used by )	r   r   r   r
   r6   r	   r   r   r/   r   s    r   getz
Waiter.get   s    ??%'&zz!JL0}}(.VZVcVc/fgg&LDM%xx( $s   B" "	B+c                     |j                   | j                  |j                         y | j                  |j                          y r   )	exceptionr/   r   r6   )r   sources     r   __call__zWaiter.__call__   s0    #KK%JJv''(r   r   )r#   
__module____qualname____doc__	__slots__r   r   r%   r(   r*   propertyr$   r/   r4   r6   r9   r=   r   r   r   r   r      sV    )V ;I  
d,' # #
?*!>%)r   c                   *    e Zd ZdZdgZddZd Zd Zy)MultipleWaitera:  
    An internal extension of Waiter that can be used if multiple objects
    must be waited on, and there is a chance that in between waits greenlets
    might be switched out. All greenlets that switch to this waiter
    will have their value returned.

    This does not handle exceptions or throw methods.
    _valuesNc                 >    t         j                  | |       g | _        y r   )r   r   rE   r   s     r   r   zMultipleWaiter.__init__   s    c" r   c                 f    | j                   j                  |       t        j                  | d       y )NT)rE   appendr   r/   )r   r   s     r   r/   zMultipleWaiter.switch   s"    E"dD!r   c                     | j                   s*t        j                  |        t        j                  |        | j                   j	                  d      S )Nr   )rE   r   r9   r   popr   s    r   r9   zMultipleWaiter.get   s6    ||JJtLL||""r   r   )r#   r>   r?   r@   rA   r   r/   r9   r   r   r   rD   rD      s     I"#r   rD   c                      t                y r   )r   r   r   r   _initrL      s    Or   )import_c_accelzgevent.__waiter)r@   
__future__r   r   r   r1   gevent._hub_localr   r   gevent.exceptionsr   __all__objectr   
__import__r
   localsr   rD   rL   gevent._utilrM   globalsr   r   r   <module>rW      s    '  % 
 7 6  	#J/:: ( G)V G)\#V #>  ( wy+ ,r   