U
    ÓB·fË  ã                   @   sú   d dl mZ d dlZzd dlZW n ek
r<   edƒ‚Y n(X d dlmZ eej	ƒedƒk rdedƒ‚d dlm
Z
mZ d dlmZ d dlZd dlZd dlmZ d d	lmZ eejd
dƒZeejddƒZddd„Zdd„ Zdd„ Zdd„ ZG dd„ deƒZdS )é    )ÚpartialNz2eventlet worker requires eventlet 0.24.1 or higher)Úparsez0.24.1)ÚhubsÚgreenthread)ÚGreenSocket)ÚAsyncWorker)Ússl_wrap_socketZ
WSGI_LOCALZALREADY_HANDLEDc           
   
   C   sð   |   ¡ dkrtdƒ‚|r"| |¡ |r0t|dƒnd}d}|j}| j}z„|rbt|| |ƒ}|dkrbqÂt||ƒƒ}|stqÂz||ƒ}	W n tk
r˜   Y qtY qtX ||	7 }|	t	|ƒk rÀ||	d … }qtqFqtqF|W ¢S |dkrêt|dƒrê| || ¡ X d S )Nr   z&non-blocking sockets are not supportedi    Úseek)
Ú
gettimeoutÚ
ValueErrorr	   ÚminÚreadÚsendÚhasattrÚ
memoryviewÚBlockingIOErrorÚlen)
ÚselfÚfileÚoffsetÚcountÚ	blocksizeÚ
total_sentÚ	file_readÚ	sock_sendÚdataÚsent© r   ú>/tmp/pip-unpacked-wheel-s8855r93/gunicorn/workers/geventlet.pyÚ_eventlet_socket_sendfile    s6    

r   c                 C   s|   t j |¡}t j ¡ }z6|  ¡ \}}| |||¡}| t||¡ d\}}}W q t j	k
rt   |  
¡  | ¡  Y dS X qdS )zÑ
    Serve requests forever.

    This code is nearly identical to ``eventlet.convenience.serve`` except
    that it attempts to join the pool at the end, which allows for gunicorn
    graceful shutdowns.
    )NNNN)ÚeventletZ	greenpoolZ	GreenPoolr   Z
getcurrentÚacceptÚspawnÚlinkÚ_eventlet_stopÚ	StopServeÚcloseZwaitall)ÚsockÚhandleZconcurrencyÚpoolZ	server_gtÚconnÚaddrÚgtr   r   r   Ú_eventlet_serveF   s    
r-   c                 C   s^   zz|  ¡  W 5 |  ¡  X W n< tjk
r2   Y n( tk
rX   tj|ft ¡ žŽ  Y nX dS )z¯
    Stop a greenlet handling a request and close its connection.

    This code is lifted from eventlet so as not to depend on undocumented
    functions in the library.
    N)	r&   ÚwaitÚgreenletZGreenletExitÚ	Exceptionr   ÚkillÚsysÚexc_info)ÚclientÚserverr*   r   r   r   r$   ]   s    r$   c                   C   s   t tdƒstt_d S )NÚsendfile)r   r   r   r6   r   r   r   r   Úpatch_sendfileo   s    

r7   c                       sd   e Zd Zdd„ Z‡ fdd„Z‡ fdd„Z‡ fdd„Z‡ fd	d
„Zdd„ Z‡ fdd„Z	dd„ Z
‡  ZS )ÚEventletWorkerc                 C   s   t  ¡  t ¡  tƒ  d S ©N)r   Zuse_hubr    Zmonkey_patchr7   ©r   r   r   r   Úpatch   s    zEventletWorker.patchc                    s,   t tdd ƒrtƒ ‚|tkr tƒ ‚tƒ  |¡S )NZalready_handled)ÚgetattrÚEVENTLET_WSGI_LOCALÚStopIterationÚEVENTLET_ALREADY_HANDLEDÚsuperÚis_already_handled)r   Zrespiter©Ú	__class__r   r   rA   „   s
    z!EventletWorker.is_already_handledc                    s   |   ¡  tƒ  ¡  d S r9   )r;   r@   Úinit_processr:   rB   r   r   rD      s    zEventletWorker.init_processc                    s   t  tƒ j||¡ d S r9   )r    r"   r@   Úhandle_quit©r   ÚsigÚframerB   r   r   rE   ‘   s    zEventletWorker.handle_quitc                    s   t  tƒ j||¡ d S r9   )r    r"   r@   Úhandle_usr1rF   rB   r   r   rI   ”   s    zEventletWorker.handle_usr1c                 C   s   t  | jjpd d¡S )NF)r    ÚTimeoutÚcfgÚ	keepaliver:   r   r   r   Útimeout_ctx—   s    zEventletWorker.timeout_ctxc                    s(   | j jrt|| j ƒ}tƒ  |||¡ d S r9   )rK   Zis_sslr   r@   r(   )r   Zlistenerr4   r+   rB   r   r   r(   š   s    zEventletWorker.handlec           	   
   C   s
  g }| j D ]H}t|ƒ}| d¡ t| j|ƒ}t t||| j¡}| 	|¡ t 
d¡ q
| jrn|  ¡  t 
d¡ qT|  ¡  d }zHt | jj¡0}|D ]}| t ¡ ¡ q|D ]}| ¡  q¨W 5 Q R X W nB tjk
r } z ||krâ‚ |D ]}| ¡  qæW 5 d }~X Y nX d S )Né   g        g      ð?)Zsocketsr   Úsetblockingr   r(   r    r"   r-   Zworker_connectionsÚappendÚsleepÚaliveÚnotifyrJ   rK   Zgraceful_timeoutr1   r%   r.   )	r   Z	acceptorsr'   ZgsockZhfunZacceptorÚtÚaÚter   r   r   ÚrunŸ   s4    


ÿ
zEventletWorker.run)Ú__name__Ú
__module__Ú__qualname__r;   rA   rD   rE   rI   rM   r(   rW   Ú__classcell__r   r   rB   r   r8   }   s   	r8   )r   N)Ú	functoolsr   r2   r    ÚImportErrorÚRuntimeErrorZpackaging.versionr   Úparse_versionÚ__version__r   r   Zeventlet.greenior   Zeventlet.wsgir/   Zgunicorn.workers.base_asyncr   Zgunicorn.sockr   r<   Zwsgir=   r?   r   r-   r$   r7   r8   r   r   r   r   Ú<module>   s*   
&