B
    H/\2                 @   s  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dl	m
Z
 dd	l	mZ dd
lmZ ddlmZ ddlmZ edje d< dd e d< eje d< eje d< e
je d< ddddddgZG dd deZG dd deZd/ddZd0ddZea d d! Z!d"d# Z"d1d$d%Z#dedfd&d'Z$defd(dZ%deefd)dZ&deefd*dZ'd+d, Z(e(  dd-lm)Z) e)e* d. dS )2z{
A collection of primitives used by the hub, and suitable for
compilation with Cython because of their frequency of use.


    )absolute_import)division)print_functionN)InvalidSwitchError)ConcurrentObjectUseError)_greenlet_primitives)_waiter)_NONE)get_hub_noargs)TimeoutZgreenlet
getcurrentc               C   s   d S )N r   r   r   5lib/python3.7/site-packages/gevent/_hub_primitives.py<lambda>   s    r   greenlet_initWaiterMultipleWaiterSwitchOutGreenletWithLoopWaitOperationsGreenletiwait_on_objectswait_on_objects	wait_read
wait_writewait_readwritec               @   s&   e Zd Zdd Zd	ddZdd ZdS )
r   c             C   sN   t | }||j| z(| }||k	r<tdt ||f W d|  X dS )z
        Wait until the *watcher* (which must not be started) is ready.

        The current greenlet will be unscheduled during this time.
        z(Invalid switch into %s: %r (expected %r)N)r   startswitchgetr   r   stop)selfwatcherZwaiterresultr   r   r   wait.   s    zWaitOperationsGreenlet.waitFc             C   s<   |dkrdS |j dk	r,| j| j||| n|r8|  dS )a  
        Cancel an in-progress call to :meth:`wait` by throwing the given *error*
        in the waiting greenlet.

        .. versionchanged:: 1.3a1
           Added the *close_watcher* parameter. If true, the watcher
           will be closed after the exception is thrown. The watcher should then
           be discarded. Closing the watcher is important to release native resources.
        .. versionchanged:: 1.3a2
           Allow the *watcher* to be ``None``. No action is taken in that case.
        N)callbackloopZrun_callback_cancel_waitclose)r   r   errorclose_watcherr   r   r   cancel_wait?   s    
z"WaitOperationsGreenlet.cancel_waitc             C   s>   |j }|j}|r|  |r:t|dd }|d k	r:|| d S )N__self__)activer"   r%   getattrthrow)r   r   r&   r'   r*   cbZgletr   r   r   r$   T   s    z#WaitOperationsGreenlet._cancel_waitN)F)__name__
__module____qualname__r!   r(   r$   r   r   r   r   r   ,   s   
c               @   sH   e Zd Zdd Zdd Zdd Zdd ZeZd	d
 Zdd Z	dd Z
dS )_WaitIteratorc             C   sV   || _ t|| _| jj| _|| _|| _d | _d| _|d krBt	|nt
|t	|| _d S )NF)_hubr   r   r   _switch_timeout_objects_timer_begunlenmin_count)r   objectshubtimeoutcountr   r   r   __init__d   s    

z_WaitIterator.__init__c             C   s`   | j r
d S d| _ x| jD ]}|| j qW | jd k	r\| jjj| jdd| _| j	| j|  d S )NT)Zpriority)
r7   r5   Zrawlinkr3   r4   r2   r#   Ztimerr6   r   )r   objr   r   r   _begins   s    
z_WaitIterator._beginc             C   s   | S )Nr   )r   r   r   r   __iter__   s    z_WaitIterator.__iter__c             C   sx   |    | jdkr |   t |  jd8  _y.| j }| j  || krZ|   t |S    |    Y nX d S )Nr      )rB   r:   _cleanupStopIterationr   r   clear)r   itemr   r   r   __next__   s    


z_WaitIterator.__next__c             C   sp   | j d k	r| j   d | _ | j}d| _xD|D ]<}t|dd }|d k	r,y|| j W q,   t  Y q,X q,W d S )Nr   unlink)r6   r%   r5   r+   r3   	traceback	print_exc)r   ZobjsZaobjrJ   r   r   r   rE      s    


z_WaitIterator._cleanupc             C   s   | S )Nr   )r   r   r   r   	__enter__   s    z_WaitIterator.__enter__c             C   s   |    d S )N)rE   )r   typvaluetbr   r   r   __exit__   s    z_WaitIterator.__exit__N)r.   r/   r0   r?   rB   rC   rI   nextrE   rM   rQ   r   r   r   r   r1   b   s   r1   c             C   s*   t  }| dkr|j|dgS t| |||S )a  
    Iteratively yield *objects* as they are ready, until all (or *count*) are ready
    or *timeout* expired.

    If you will only be consuming a portion of the *objects*, you should
    do so inside a ``with`` block on this object to avoid leaking resources::

        with gevent.iwait((a, b, c)) as it:
            for i in it:
                if i is a:
                    break

    :param objects: A sequence (supporting :func:`len`) containing objects
        implementing the wait protocol (rawlink() and unlink()).
    :keyword int count: If not `None`, then a number specifying the maximum number
        of objects to wait for. If ``None`` (the default), all objects
        are waited for.
    :keyword float timeout: If given, specifies a maximum number of seconds
        to wait. If the timeout expires before the desired waited-for objects
        are available, then this method returns immediately.

    .. seealso:: :func:`wait`

    .. versionchanged:: 1.1a1
       Add the *count* parameter.
    .. versionchanged:: 1.1a2
       No longer raise :exc:`LoopExit` if our caller switches greenlets
       in between items yielded by this function.
    .. versionchanged:: 1.4
       Add support to use the returned object as a context manager.
    N)r=   )get_hubjoinr1   )r;   r=   r>   r<   r   r   r   r      s    !c             C   s*   | dkrt  }|j|dS tt| ||S )ax  
    Wait for ``objects`` to become ready or for event loop to finish.

    If ``objects`` is provided, it must be a list containing objects
    implementing the wait protocol (rawlink() and unlink() methods):

    - :class:`gevent.Greenlet` instance
    - :class:`gevent.event.Event` instance
    - :class:`gevent.lock.Semaphore` instance
    - :class:`gevent.subprocess.Popen` instance

    If ``objects`` is ``None`` (the default), ``wait()`` blocks until
    the current event loop has nothing to do (or until ``timeout`` passes):

    - all greenlets have finished
    - all servers were stopped
    - all event loop watchers were stopped.

    If ``count`` is ``None`` (the default), wait for all ``objects``
    to become ready.

    If ``count`` is a number, wait for (up to) ``count`` objects to become
    ready. (For example, if count is ``1`` then the function exits
    when any object in the list is ready).

    If ``timeout`` is provided, it specifies the maximum number of
    seconds ``wait()`` will block.

    Returns the list of ready objects, in the order in which they were
    ready.

    .. seealso:: :func:`iwait`
    N)r=   )rS   rT   listr   )r;   r=   r>   r<   r   r   r   r      s    "c             C   s   | a d S )N)_timeout_error)er   r   r   set_default_timeout_error  s    rX   c          	   C   s   | j d k	rtd| j f |d kr(t }|d kr>||  d S t||tk	sT|d krX|ntd}| ||  W d Q R X d S )Nz3This socket is already used by another greenlet: %rz	timed out)r"   r   rS   r!   r   Z_start_new_or_dummyr	   rV   )r   r=   timeout_excr<   r   r   r   _primitive_wait  s    


rZ   c             C   s:   | d ks|d krt dt|| j|d k	r,|nt| j d S )Nz6The socket has already been closed by another greenlet)r   rZ   r=   r	   r<   )Zsocketr   rY   r   r   r   wait_on_socket  s
    r[   c             C   s   t | ||| dS )a  
    wait(watcher, timeout=None, [timeout_exc=None]) -> None

    Block the current greenlet until *watcher* is ready.

    If *timeout* is non-negative, then *timeout_exc* is raised after
    *timeout* second has passed.

    If :func:`cancel_wait` is called on *io* by another greenlet,
    raise an exception in this blocking greenlet
    (``socket.error(EBADF, 'File descriptor was closed in another
    greenlet')`` by default).

    :param io: An event loop watcher, most commonly an IO watcher obtained from
        :meth:`gevent.core.loop.io`
    :keyword timeout_exc: The exception to raise if the timeout expires.
        By default, a :class:`socket.timeout` exception is raised.
        If you pass a value for this keyword, it is interpreted as for
        :class:`gevent.timeout.Timeout`.

    :raises ~gevent.hub.ConcurrentObjectUseError: If the *watcher* is
        already started.
    N)rZ   )r   r=   rY   r<   r   r   r   wait_on_watcher%  s    r\   c             C   s2   t  }|j| d}zt||||S |  X dS )a  
    wait_read(fileno, timeout=None, [timeout_exc=None]) -> None

    Block the current greenlet until *fileno* is ready to read.

    For the meaning of the other parameters and possible exceptions,
    see :func:`wait`.

    .. seealso:: :func:`cancel_wait`
    rD   N)rS   r#   ior\   r%   )filenor=   rY   r<   r]   r   r   r   r   @  s
    c             C   s2   t  }|j| d}zt||||S |  X dS )a  
    wait_write(fileno, timeout=None, [timeout_exc=None]) -> None

    Block the current greenlet until *fileno* is ready to write.

    For the meaning of the other parameters and possible exceptions,
    see :func:`wait`.

    .. deprecated:: 1.1
       The keyword argument *event* is ignored. Applications should not pass this parameter.
       In the future, doing so will become an error.

    .. seealso:: :func:`cancel_wait`
       N)rS   r#   r]   r\   r%   )r^   r=   rY   eventr<   r]   r   r   r   r   S  s
    c             C   s2   t  }|j| d}zt||||S |  X dS )a  
    wait_readwrite(fileno, timeout=None, [timeout_exc=None]) -> None

    Block the current greenlet until *fileno* is ready to read or
    write.

    For the meaning of the other parameters and possible exceptions,
    see :func:`wait`.

    .. deprecated:: 1.1
       The keyword argument *event* is ignored. Applications should not pass this parameter.
       In the future, doing so will become an error.

    .. seealso:: :func:`cancel_wait`
       N)rS   r#   r]   r\   r%   )r^   r=   rY   r`   r<   r]   r   r   r   r   k  s
    c               C   s
   t   d S )N)r   r   r   r   r   _init  s    rb   )import_c_accelzgevent.__hub_primitives)NN)NNN)N)+__doc__Z
__future__r   r   r   rK   Zgevent.exceptionsr   r   Zgeventr   r   Zgevent._utilr	   Zgevent._hub_localr
   rS   Zgevent.timeoutr   
__import__r   localsr   r   r   __all__r   objectr1   r   r   	ExceptionrV   rX   rZ   r[   r\   r   r   r   rb   rc   globalsr   r   r   r   <module>	   sL   6P
'
'
	