3
Z_ð]L-  ã               @   s   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Zd dlZd	d
ddddddgZejZd(dd
„Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ ZeZdd„ Zdd„ ddejfd d!ejffD ƒ\ZZd"d#„ ZG d$d„ dejƒZd%d&„ Zd'd„ Z dS ))é    )ÚdequeN)Úevent)Úhubs)Úsupport)Útimeout)Útimer)Ú	greenletsÚ
getcurrentÚsleepÚspawnÚspawn_nÚkillÚspawn_afterÚspawn_after_localÚGreenThreadc          
   C   sJ   t jƒ }tƒ }|j|k	s tdƒ‚|j| |jƒ}z|jƒ  W d|jƒ  X dS )a	  Yield control to another eligible coroutine until at least *seconds* have
    elapsed.

    *seconds* may be specified as an integer, or a float if fractional seconds
    are desired. Calling :func:`~greenthread.sleep` with *seconds* of 0 is the
    canonical way of expressing a cooperative yield. For example, if one is
    looping over a large list performing an expensive calculation without
    calling any socket methods, it's a good idea to call ``sleep(0)``
    occasionally; otherwise nothing else will run.
    z0do not call blocking functions from the mainloopN)r   Úget_hubr	   ÚgreenletÚAssertionErrorÚschedule_call_globalÚswitchÚcancel)ÚsecondsÚhubÚcurrentr   © r   ú8/tmp/pip-build-yz_zf6az/eventlet/eventlet/greenthread.pyr
      s    c             O   s*   t jƒ }t|jƒ}|jd|j| ||ƒ |S )a”  Create a greenthread to run ``func(*args, **kwargs)``.  Returns a
    :class:`GreenThread` object which you can use to get the results of the
    call.

    Execution control returns immediately to the caller; the created greenthread
    is merely scheduled to be run at the next available opportunity.
    Use :func:`spawn_after` to  arrange for greenthreads to be spawned
    after a finite delay.
    r   )r   r   r   r   r   r   )ÚfuncÚargsÚkwargsr   Úgr   r   r   r   )   s    

c             O   s   t d| ||ƒd S )a°  Same as :func:`spawn`, but returns a ``greenlet`` object from
    which it is not possible to retrieve either a return value or
    whether it raised any exceptions.  This is faster than
    :func:`spawn`; it is fastest if there are no keyword arguments.

    If an exception is raised in the function, spawn_n prints a stack
    trace; the print can be disabled by calling
    :func:`eventlet.debug.hub_exceptions` with False.
    r   é   )Ú_spawn_n)r   r   r   r   r   r   r   9   s    
c             O   s*   t jƒ }t|jƒ}|j| |j|||ƒ |S )ah  Spawns *func* after *seconds* have elapsed.  It runs as scheduled even if
    the current greenthread has completed.

    *seconds* may be specified as an integer, or a float if fractional seconds
    are desired. The *func* will be called with the given *args* and
    keyword arguments *kwargs*, and will be executed within its own greenthread.

    The return value of :func:`spawn_after` is a :class:`GreenThread` object,
    which can be used to retrieve the results of the call.

    To cancel the spawn and prevent *func* from being called,
    call :meth:`GreenThread.cancel` on the return value of :func:`spawn_after`.
    This will not abort the function if it's already started running, which is
    generally the desired behavior.  If terminating *func* regardless of whether
    it's started or not is the desired behavior, call :meth:`GreenThread.kill`.
    )r   r   r   r   r   r   )r   r   r   r   r   r   r   r   r   r   F   s    
c             O   s*   t jƒ }t|jƒ}|j| |j|||ƒ |S )a+  Spawns *func* after *seconds* have elapsed.  The function will NOT be
    called if the current greenthread has exited.

    *seconds* may be specified as an integer, or a float if fractional seconds
    are desired. The *func* will be called with the given *args* and
    keyword arguments *kwargs*, and will be executed within its own greenthread.

    The return value of :func:`spawn_after` is a :class:`GreenThread` object,
    which can be used to retrieve the results of the call.

    To cancel the spawn and prevent *func* from being called,
    call :meth:`GreenThread.cancel` on the return value. This will not abort the
    function if it's already started running.  If terminating *func* regardless
    of whether it's started or not is the desired behavior, call
    :meth:`GreenThread.kill`.
    )r   r   r   r   Úschedule_call_localr   )r   r   r   r   r   r   r   r   r   r   ]   s    
c             O   s"   t jdtdd� t| |||ƒd S )Nzªcall_after_global is renamed to spawn_after, whichhas the same signature and semantics (plus a bit extra).  Please do a quick search-and-replace on your codebase, thanks!é   )Ú
stacklevelr   )ÚwarningsÚwarnÚDeprecationWarningr!   )r   r   r   r   r   r   r   Úcall_after_globalt   s    
r(   c             O   sB   t jdtdd� tjƒ }tj||jd�}|j| |jf|ž|Ž}|S )Nzocall_after_local is renamed to spawn_after_local, whichhas the same signature and semantics (plus a bit extra).r#   )r$   )Úparent)r%   r&   r'   r   r   r   r"   r   )r   Úfunctionr   r   r   r   Útr   r   r   Úcall_after_local}   s    
r,   c             G   sF   t jdtdd� | d kr(tj| dd„ ƒS tjƒ }|j| tƒ j	f|žŽ S )NzJInstead of exc_after, which is deprecated, use Timeout(seconds, exception)r#   )r$   c               S   s   d S )Nr   r   r   r   r   Ú<lambda>�   s    zexc_after.<locals>.<lambda>)
r%   r&   r'   r   ÚTimerr   r   r"   r	   Úthrow)r   Ú
throw_argsr   r   r   r   Ú	exc_after‹   s    
r1   c             c   s$   | ]\}}}t j||ƒ|ƒV  qd S )N)r   Zwrap_deprecated)Ú.0ÚoldÚnewZfunr   r   r   ú	<genexpr>–   s    r5   zgreenthread.TimeoutErrorÚTimeoutzgreenthread.with_timeoutÚwith_timeoutc             C   s6   t jƒ }tj||jd�}|j| |jf|ž|Ž}||fS )N)r)   )r   r   r   r   r   )r   r   r   r   r   r   r+   r   r   r   r!   œ   s    r!   c               @   sP   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ Zdd„ Z	dd„ Z
dd„ ZdS )r   zéThe GreenThread class is a type of Greenlet which has the additional
    property of being able to retrieve the return value of the main function.
    Do not construct GreenThread objects directly; call :func:`spawn` to get one.
    c             C   s,   t j j| | j|ƒ tjƒ | _d| _d | _d S )NF)r   Ú__init__Úmainr   ÚEventÚ_exit_eventÚ_resolving_linksÚ_exit_funcs)Úselfr)   r   r   r   r8   ©   s    
zGreenThread.__init__c             C   s
   | j jƒ S )aH   Returns the result of the main function of this GreenThread.  If the
        result is a normal return value, :meth:`wait` returns it.  If it raised
        an exception, :meth:`wait` will raise the same exception (though the
        stack trace will unavoidably contain some frames from within the
        greenthread module).)r;   Úwait)r>   r   r   r   r?   ¯   s    zGreenThread.waitc             O   s:   | j dkrtƒ | _ | j j|||fƒ | jjƒ r6| jƒ  dS )aÓ   Set up a function to be called with the results of the GreenThread.

        The function must have the following signature::

            def func(gt, [curried args/kwargs]):

        When the GreenThread finishes its run, it calls *func* with itself
        and with the `curried arguments <http://en.wikipedia.org/wiki/Currying>`_ supplied
        at link-time.  If the function wants to retrieve the result of the GreenThread,
        it should call wait() on its first argument.

        Note that *func* is called within execution context of
        the GreenThread, so it is possible to interfere with other linked
        functions by doing things like switching explicitly to another
        greenthread.
        N)r=   r   Úappendr;   ÚreadyÚ_resolve_links)r>   r   Úcurried_argsÚcurried_kwargsr   r   r   Úlink·   s
    

zGreenThread.linkc             O   s:   | j s
dS y| j j|||fƒ dS  tk
r4   dS X dS )zn remove linked function set by :meth:`link`

        Remove successfully return True, otherwise False
        FTN)r=   ÚremoveÚ
ValueError)r>   r   rC   rD   r   r   r   ÚunlinkÎ   s    zGreenThread.unlinkc          	   C   sN   y|||Ž}W n&   | j jtjƒ Ž  | jƒ  ‚ Y nX | j j|ƒ | jƒ  d S )N)r;   Zsend_exceptionÚsysÚexc_inforB   Úsend)r>   r*   r   r   Úresultr   r   r   r9   Û   s    zGreenThread.mainc             C   sX   | j r
d S | jsd S d| _ z0x*| jrF| jjƒ \}}}|| f|ž|Ž qW W d d| _ X d S )NTF)r<   r=   Úpopleft)r>   ÚfÚcaZckwr   r   r   rB   æ   s    zGreenThread._resolve_linksc             G   s   t | f|žŽ S )z²Kills the greenthread using :func:`kill`.  After being killed
        all calls to :meth:`wait` will raise *throw_args* (which default
        to :class:`greenlet.GreenletExit`).)r   )r>   r0   r   r   r   r   ô   s    zGreenThread.killc             G   s   t | f|žŽ S )zìKills the greenthread using :func:`kill`, but only if it hasn't
        already started running.  After being canceled,
        all calls to :meth:`wait` will raise *throw_args* (which default
        to :class:`greenlet.GreenletExit`).)r   )r>   r0   r   r   r   r   ú   s    zGreenThread.cancelN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r8   r?   rE   rH   r9   rB   r   r   r   r   r   r   r   £   s   c             G   s   | st | f|žŽ  dS )z¶Like :func:`kill`, but only terminates the greenthread if it hasn't
    already started execution.  If the grenthread has already started
    execution, :func:`cancel` has no effect.N)r   )r   r0   r   r   r   r     s    r   c          
      s†   | j r
dS tjƒ }| sR‡ fdd„}|| _t| tƒrRy| j|f i ƒ W n   Y nX tƒ }||jk	rx|j	ƒ  |j
d|jƒ | jˆ Ž  dS )aê  Terminates the target greenthread by raising an exception into it.
    Whatever that greenthread might be doing; be it waiting for I/O or another
    primitive, it sees an exception right away.

    By default, this exception is GreenletExit, but a specific exception
    may be specified.  *throw_args* should be the same as the arguments to
    raise; either an exception instance or an exc_info tuple.

    Calling :func:`kill` causes the calling greenthread to cooperatively yield.
    Nc                 s,   ˆ r t jˆ d ˆ d ˆ d ƒ ntjƒ ‚d S )Nr   r    r#   )ÚsixÚreraiser   ZGreenletExit)ÚaÚkw)r0   r   r   Ú
just_raise  s    zkill.<locals>.just_raiser   )Zdeadr   r   ÚrunÚ
isinstancer   r9   r	   r   Zensure_greenletr   r   r/   )r   r0   r   rX   r   r   )r0   r   r   
  s     

)r   )!Úcollectionsr   rI   Zeventletr   r   r   r   Zeventlet.hubsr   Zeventlet.supportr   r   rT   r%   Ú__all__r	   r
   r   r   r   r   r(   r,   Z
call_afterr1   r6   r7   ÚTimeoutErrorr!   r   r   r   r   r   r   r   Ú<module>   s:   

	
_