3
Z_ð]Ú)  ã               @   s<  d dl Z d dlZd dlZd dlZd dlZd dlZd dlmZmZmZm	Z	m
Z
 d dlZddddgZee
jfZeeefZdZe	jdƒZe	jd	ƒZejrœe	jd
ƒZejr¬e	jdƒZejZejZdZdaeej j!ddƒƒa"d a#a$d a%a&da'g Z(dd„ Z)dd„ Z*dd„ Z+dd„ Z,G dd„ de-ƒZ.dd„ Z/e j0dd„ ƒZ1dd„ Z2dS )é    N)ÚeventÚgreenioÚgreenthreadÚpatcherÚtimeoutÚexecuteÚProxyÚkillallÚset_num_threadsTÚsocketÚ	threadingÚQueueÚqueueó    ZEVENTLET_THREADPOOL_SIZEé   Fc              C   s‚   x|yt jdƒ} | st‚W n tk
r.   P Y nX xHtjƒ sxy&tjdd�\}}|j|ƒ d  }}W q2 tk
rt   Y q2X q2W qW d S )Né   F)Úblock)	Ú_rsockÚrecvÚAssertionErrorÚ
ValueErrorÚ_rspqÚemptyÚgetÚsendÚEmpty)Z_cÚeÚrv© r   ú2/tmp/pip-build-yz_zf6az/eventlet/eventlet/tpool.pyÚtpool_trampoline5   s    


r    c              C   sà   xÚyt jƒ } W n tk
r"   d S X | d kr0d S | \}}}}d }y|||Ž}W nJ tk
rd   ‚ Y n6 tk
r˜   tjƒ }tjdkr”tj	|d j
ƒ Y nX tjr¨tjƒ  tj||fƒ d  }  } } } }}tjtƒ qW d S )Né   é   r   )r!   r"   )Ú_reqqr   ÚAttributeErrorÚSYS_EXCSÚEXC_CLASSESÚsysÚexc_infoÚversion_infoÚ	tracebackÚclear_framesÚ__traceback__ÚsixÚPY2Z	exc_clearr   ÚputÚ_wsockÚsendallÚ_bytetosend)Úmsgr   ÚmethÚargsÚkwargsr   r   r   r   ÚtworkerG   s,    
r7   c             O   s¬   t ƒ  tjƒ }|tks&tjƒ s&tdkr0| ||ŽS tjƒ }t	j
|| ||fƒ |jƒ }t|tƒr¨t|ƒdkr¨t|d tƒr¨|\}}}tsštj|||ƒ tjƒ  tj|||ƒ |S )aÊ  
    Execute *meth* in a Python thread, blocking the current coroutine/
    greenthread until the method completes.

    The primary use case for this is to wrap an object or module that is not
    amenable to monkeypatching or any of the other tricks that Eventlet uses
    to achieve cooperative yielding.  With tpool, you can force such objects to
    cooperate with green threads by sticking them in native threads, at the cost
    of some overhead.
    r   r!   r   )Úsetupr   ÚcurrentThreadÚ_threadsÚimpÚ	lock_heldÚ	_nthreadsr   ÚEventr#   r/   ÚwaitÚ
isinstanceÚtupleÚlenr&   ÚQUIETr*   Úprint_exceptionÚprint_stackr-   Úreraise)r4   r5   r6   Z	my_threadr   r   ÚcÚtbr   r   r   r   c   s     


c             O   sD   |j ddƒr|||Ž}nt|f|ž|Ž}t|| ƒr<t|| ƒS |S dS )a  
    Call a function *f* and returns the value.  If the type of the return value
    is in the *autowrap* collection, then it is wrapped in a :class:`Proxy`
    object before return.

    Normally *f* will be called in the threadpool with :func:`execute`; if the
    keyword argument "nonblocking" is set to ``True``, it will simply be
    executed directly.  This is useful if you have an object which has methods
    that don't need to be called in a separate thread, but which return objects
    that should be Proxy wrapped.
    ZnonblockingFN)Úpopr   r@   r   )ÚautowrapÚfr5   r6   r   r   r   r   Ú
proxy_call…   s    

rL   c               @   sª   e Zd ZdZf f fdd„Zdd„ Zdd„ Zdd	„ Zd%dd„Zd&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d„ Zdd „ ZeZd!d"„ Zd#d$„ ZeZd
S )'r   aý  
    a simple proxy-wrapper of any object that comes with a
    methods-only interface, in order to forward every method
    invocation onto a thread in the native-thread pool.  A key
    restriction is that the object's methods should not switch
    greenlets or use Eventlet primitives, since they are in a
    different thread from the main hub, and therefore might behave
    unexpectedly.  This is for running native-threaded code
    only.

    It's common to want to have some of the attributes or return
    values also wrapped in Proxy objects (for example, database
    connection objects produce cursor objects which also should be
    wrapped in Proxy objects to remain nonblocking).  *autowrap*, if
    supplied, is a collection of types; if an attribute or return
    value matches one of those types (via isinstance), it will be
    wrapped in a Proxy.  *autowrap_names* is a collection
    of strings, which represent the names of attributes that should be
    wrapped in Proxy objects when accessed.
    c             C   s   || _ || _|| _d S )N)Ú_objÚ	_autowrapÚ_autowrap_names)ÚselfÚobjrJ   Zautowrap_namesr   r   r   Ú__init__±   s    zProxy.__init__c                sP   t ˆjˆ ƒ‰tˆdƒs<tˆˆjƒs,ˆ ˆjkr8tˆˆjƒS ˆS ‡ ‡‡fdd„}|S )NÚ__call__c                 s6   t ˆjˆf| ž|Ž}ˆ ˆjkr2t|tƒ r2t|ƒS |S )N)rL   rN   rO   r@   r   )r5   r6   Úresult)Ú	attr_namerK   rP   r   r   Údoit½   s    zProxy.__getattr__.<locals>.doit)ÚgetattrrM   Úhasattrr@   rN   rO   r   )rP   rU   rV   r   )rU   rK   rP   r   Ú__getattr__¶   s    
zProxy.__getattr__c             C   s   t | j| jj|ƒS )N)rL   rN   rM   Ú__getitem__)rP   Úkeyr   r   r   rZ   Ç   s    zProxy.__getitem__c             C   s   t | j| jj||ƒS )N)rL   rN   rM   Ú__setitem__)rP   r[   Úvaluer   r   r   r\   Ê   s    zProxy.__setitem__Nc             C   s   t | j| jj|ƒS )N)rL   rN   rM   Ú__deepcopy__)rP   Úmemor   r   r   r^   Í   s    zProxy.__deepcopy__c             C   s   t | j| jj|ƒS )N)rL   rN   rM   Ú__copy__)rP   r_   r   r   r   r`   Ð   s    zProxy.__copy__c             O   s>   d| j kr$tt| j| jf|ž|ŽƒS t| j| jf|ž|ŽS d S )NrS   )rO   r   rL   rN   rM   )rP   ÚaÚkwr   r   r   rS   Ó   s    
zProxy.__call__c             C   s   t | j| jjƒS )N)rL   rN   rM   Ú	__enter__)rP   r   r   r   rc   Ù   s    zProxy.__enter__c             G   s   t | j| jjf|žŽ S )N)rL   rN   rM   Ú__exit__)rP   Úexcr   r   r   rd   Ü   s    zProxy.__exit__c             C   s
   | j |kS )N)rM   )rP   Úrhsr   r   r   Ú__eq__â   s    zProxy.__eq__c             C   s
   | j jƒ S )N)rM   Ú__hash__)rP   r   r   r   rh   å   s    zProxy.__hash__c             C   s
   | j jƒ S )N)rM   Ú__repr__)rP   r   r   r   ri   è   s    zProxy.__repr__c             C   s
   | j jƒ S )N)rM   Ú__str__)rP   r   r   r   rj   ë   s    zProxy.__str__c             C   s
   t | jƒS )N)rB   rM   )rP   r   r   r   Ú__len__î   s    zProxy.__len__c             C   s
   t | jƒS )N)ÚboolrM   )rP   r   r   r   Ú__nonzero__ñ   s    zProxy.__nonzero__c             C   s$   t | jƒ}|| jkr| S t|ƒS d S )N)ÚiterrM   r   )rP   Úitr   r   r   Ú__iter__ö   s    

zProxy.__iter__c             C   s   t | jt| jƒS )N)rL   rN   ÚnextrM   )rP   r   r   r   rq   ý   s    z
Proxy.next)N)N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__rR   rY   rZ   r\   r^   r`   rS   rc   rd   rg   rh   ri   rj   rk   rm   Ú__bool__rp   rq   Ú__next__r   r   r   r   r   ›   s(   

c              C   s@  t rd S da tdkstdƒ‚tdkr8dd l} | jdtƒ td
d�atdd�at	j	t	j
t	jƒ}|jdƒ |jdƒ t	j	t	j
t	jƒ}|j|jƒ ƒ |jt	jt	jdƒ |jƒ \a}tjd ƒ tjt	jt	jdƒ |jƒ  tj|ƒatjd ƒ xBtjjtƒD ]2}tjtd| d	�}|j dƒ |j!ƒ  t"j#|ƒ qòW t$j%t&ƒa't(j)dƒ d S )NTr   z(Can't specify negative number of threadszªZero threads in tpool.  All tpool.execute calls will            execute in main thread.  Check the value of the environment             variable EVENTLET_THREADPOOL_SIZE.r   )Úmaxsizeú	127.0.0.1ztpool_thread_%s)ÚtargetÚnameéÿÿÿÿr|   )ry   r   )*Ú_setup_alreadyr=   r   ÚwarningsÚwarnÚRuntimeWarningr   r#   r   r   ÚAF_INETÚSOCK_STREAMÚbindÚlistenÚconnectÚgetsocknameÚ
setsockoptÚIPPROTO_TCPÚTCP_NODELAYÚacceptr0   Ú
settimeoutÚcloser   ZGreenSocketr   r-   ÚmovesÚranger   ÚThreadr7   Ú	setDaemonÚstartr:   Úappendr   Zspawn_nr    Ú_coroÚeventletÚsleep)r~   ÚsockZcsockZ_addrÚiÚtr   r   r   r8     s<    








r8   c              C   sä   t sd S tjdƒ xtD ]} tjd ƒ qW xtD ]} | jƒ  q0W td d …= xRtd k	rœtjƒ  rœy&tj	dd�\}}|j
|ƒ d  }}W qL tk
r˜   Y qLX qLW td k	r°tjtƒ td k	rÄtjƒ  d atd k	rØtjƒ  d ad ada d S )Nr   F)r   )r}   r”   r•   r:   r#   r/   Újoinr   r   r   r   r   r“   r   Úkillr   rŒ   r0   )Zthrr   r   r   r   r   r	   .  s2    






c             C   s   | a d S )N)r=   )Znthreadsr   r   r   r
   R  s    )3Úatexitr;   Úosr'   r*   r”   r   r   r   r   r   r-   Ú__all__Ú	ExceptionÚTimeoutr&   ÚGeneratorExitÚKeyboardInterruptÚ
SystemExitr%   rC   Úoriginalr   r   r.   ZQueue_moduleÚPY3r   r   r2   r“   ÚintÚenvironr   r=   r#   r   r   r0   r}   r:   r    r7   r   rL   Úobjectr   r8   Úregisterr	   r
   r   r   r   r   Ú<module>   sD   





"h+$