B
    ÐH/\„\  ã               @   s2  d Z ddlmZmZ ddl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jZejZg ZG dd„ deƒZeeeedddgƒZddlmZ eZddlmZ  e j!Z!ej"Z#ej$Z%dd„ Z&dd„ Z'dd„ Z(eeƒG dd„ deƒƒZ)dS )z
libuv loop implementation
é    )Úabsolute_importÚprint_functionN)Údefaultdict)Ú
namedtuple)Údelitem)Ú_dbg)ÚAbstractLoop)Ú	_corecffi)Úassign_standard_callbacks)ÚAbstractCallbacks)Úimplementer)ÚILoopc               @   s,   e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zd	S )
Ú
_Callbacksc             C   s    t  d|¡j}|r|  |¡S d S )Nzuv_handle_t*)ÚffiÚcastÚdataÚfrom_handle)ÚselfÚwatcher_ptrZloop_handle© r   ú0lib/python3.7/site-packages/gevent/libuv/loop.pyÚ_find_loop_from_c_watcher   s    z$_Callbacks._find_loop_from_c_watcherc             C   s   |   t d|¡j¡ ¡  d S )Nzuv_handle_t*)r   r   r   r   Ú_sigchld_callback)r   r   Z_signumr   r   r   Úpython_sigchld_callback"   s    z"_Callbacks.python_sigchld_callbackc             C   s
   |   |¡S )N)Úpython_prepare_callback)r   r   r   r   r   Úpython_timer0_callback%   s    z!_Callbacks.python_timer0_callbackc             C   s"   |j }|  |¡}|j ||¡ d S )N)r   r   ÚloopÚ_queue_callback)r   r   ÚreventsZwatcher_handleZthe_watcherr   r   r   Úpython_queue_callback(   s    
z _Callbacks.python_queue_callbackN)Ú__name__Ú
__module__Ú__qualname__r   r   r   r   r   r   r   r   r      s   r   )r   N)r   N)r   N)ÚEVENTS)Úwatcherc              C   s0   t  t ¡ ¡} t| tƒs$|  d¡}n| }d| S )NÚasciizlibuv-)r   ÚstringÚlibuvZuv_version_stringÚ
isinstanceÚstrÚdecode)Zuv_bytesZuv_strr   r   r   Úget_version?   s
    
r+   c               C   s   dt jt jt jf S )Nzlibuv-%d.%d.%d)r'   ZUV_VERSION_MAJORZUV_VERSION_MINORZUV_VERSION_PATCHr   r   r   r   Úget_header_versionI   s    r,   c               C   s   dgS )NÚdefaultr   r   r   r   r   Úsupported_backendsL   s    r.   c                   s6  e Zd ZdZdZdZdZdZeZdDdd„Z	dd	„ Z
d
d„ ZdZdd„ Z‡ f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d"d#„ Zd$d%„ ZdEd&d'„Zd(d)„ Zd*Zd+d,„ ZdFd-d.„Zd/d0„ Zd1d2„ Z d3d4„ Z!dZ"dZ#d5d6„ Z$d7d8„ Z%d9d:„ Z&d;d<„ Z'd=d>„ Z(dGd@dA„Z)dHdBdC„Z*‡  Z+S )Ir   gü©ñÒMbP?Nzuv_check_t *zuv_prepare_t *zvoid(*)(void*)c             C   s\   t  | ttt||¡ t ¡ | _tt	ƒ| _
tƒ | _tƒ | _t ¡ | _| jt ¡ k| _g | _d S )N)r   Ú__init__r   r'   Ú	_watchersÚosÚgetpidZ_loop__loop_pidr   ÚlistÚ_child_watchersÚdictÚ_io_watchersÚsetÚ_fork_watchersÚ_pidÚ_ptrÚuv_default_loopZ_defaultÚ_queued_callbacks)r   Úflagsr-   r   r   r   r/   `   s    


zloop.__init__c             C   s   | j  ||f¡ d S )N)r<   Úappend)r   r   r   r   r   r   r   j   s    zloop._queue_callbackc             C   s8   |d krd}|rt  ¡ }nt  ¡ }|s.tdƒ‚||_|S )NTzFailed to get loop)r'   r;   Zuv_loop_newÚSystemErrorr   )r   r=   r-   Úptrr   r   r   Ú
_init_loopm   s    
zloop._init_loopc             C   s‚   t  | j| j¡ t  | jt j¡ t  | j¡ t d¡| _	t  
| j| j	¡ | j| j	_t dt j¡}t  | j	|dd¡ t  | j	¡ d S )Nzuv_timer_t*zvoid(*)(uv_timer_t*)i,  )r'   Úuv_check_initr:   Ú_checkÚuv_check_startZpython_check_callbackÚuv_unrefr   ÚnewÚ_signal_idleZuv_timer_initÚ_handle_to_selfr   r   Zuv_timer_start)r   Zsig_cbr   r   r   Ú_init_and_start_check†   s    
zloop._init_and_start_checkc                sL   t  ¡ }|| jkr0|| _x| jD ]}| ¡  q W |  ¡ | _tt| ƒ 	¡  d S )N)
r1   r2   r9   r8   Z_on_forkÚ_loop__run_queued_callbacksÚ_prepare_ran_callbacksÚsuperr   Ú_run_callbacks)r   Zcurpidr$   )Ú	__class__r   r   rM   ¢   s    

zloop._run_callbacksc             C   s0   t  | j| j¡ t  | jt j¡ t  | j¡ d S )N)r'   Zuv_prepare_initr:   Ú_prepareZuv_prepare_startr   rE   )r   r   r   r   Ú_init_and_start_prepareÃ   s    zloop._init_and_start_preparec             C   s   t  | j| j¡ d S )N)r'   rB   r:   Ú_timer0)r   r   r   r   Ú_init_callback_timerÈ   s    zloop._init_callback_timerc             C   s   t  | j¡ d S )N)r'   Úuv_check_stoprQ   )r   r   r   r   Ú_stop_callback_timerË   s    zloop._stop_callback_timerc             C   s   t  | jt j¡ d S )N)r'   rD   rQ   r   )r   r   r   r   Ú_start_callback_timerÎ   s    Vzloop._start_callback_timerc             C   sv   | j s
t‚| jst‚| jst‚t | j ¡ t | j ¡ t | j¡ t | j¡ t | j¡ t | j¡ t | j	¡ d S )N)
rO   ÚAssertionErrorrC   rG   r'   Zuv_prepare_stopÚuv_refrS   Zuv_timer_stoprQ   )r   r   r   r   Ú_stop_aux_watchers'  s    


zloop._stop_aux_watchersc             C   s   |   ¡  t | j¡ d S )N)rU   r'   rW   rQ   )r   r   r   r   Ú_setup_for_run_callback6  s    zloop._setup_for_run_callbackc             C   s   |j S )N)r   )r   r@   r   r   r   Ú_can_destroy_loop;  s    zloop._can_destroy_loopc             C   sÌ   t j|_t |¡ t |¡ t |¡}|rr|tjks8t‚t 	|tj
¡}|rXt 	|tj¡ t |¡}|dksrt|ƒ‚t | j¡ t | j¡ t | j¡ t | j¡ | `| `| `| `t |¡ | `| `| `d S )Nr   )r   ÚNULLr   r'   Úuv_stopZgevent_close_all_handlesZuv_loop_closeZUV_EBUSYrV   Úuv_runÚUV_RUN_ONCEÚUV_RUN_NOWAITZgevent_zero_checkrC   rQ   Zgevent_zero_preparerO   Zgevent_zero_timerrG   Zgevent_zero_loopr6   r8   r4   )r   r@   Zclosed_failedZran_has_more_callbacksr   r   r   Ú_destroy_loopC  s.    




zloop._destroy_loopc                sF   t dddddddgƒ‰ g ‰‡ ‡fdd	„}t | jt d
|¡tj¡ ˆS )zL
        Return all the handles that are open and their ref status.
        ZHandleStateÚhandleÚtyper$   ÚrefZactiveÚclosingc                sV   | j }|rt |¡}nd }ˆ ˆ | t t | j¡¡|t | ¡t 	| ¡t 
| ¡ƒ¡ d S )N)r   r   r   r>   r&   r'   Zuv_handle_type_namerb   Z
uv_has_refÚuv_is_activeZuv_is_closing)ra   Z_argr   r$   )Úhandle_stateÚhandlesr   r   Úwalkw  s    zloop.debug.<locals>.walkzvoid(*)(uv_handle_t*,void*))r   r'   Zuv_walkr:   r   Úcallbackr[   )r   rh   r   )rf   rg   r   Údebugi  s    z
loop.debugc             C   s   d S )Nr   )r   r   r   r   rc   Š  s    zloop.refc             C   s   d S )Nr   )r   r   r   r   Úunref  s    z
loop.unrefc             C   s   t  | j¡ d S )N)r'   r\   r:   )r   Zhowr   r   r   Úbreak_‘  s    zloop.break_c             C   s   t  | j¡ d S )N)r'   Zuv_loop_forkr:   )r   r   r   r   Úreinit”  s    zloop.reinitFc             C   s¤   | j s
dS t| j ƒ}g | _ x„|D ]|\}}|j}|sBt |¡r t‚q t ||¡}|dkrdt ||¡ q |dkr t |¡s |j|kr’|jrœt 	d ¡ q t 	|¡ q W dS )NFéÿÿÿÿé   T)
r<   r3   r   r'   re   rV   Ú
_callbacksZpython_callbackZpython_handle_errorZpython_stop)r   Zcbsr   Úargra   Úvalr   r   r   Z__run_queued_callbacks®  s&    


zloop.__run_queued_callbacksc             C   sŽ   t j}|rt j}|rt j}|t jkrtxJ| jrn| jjrn|  ¡  d| _t  | jt j¡}|  	¡ }|s&|s&| js&|S q&W dS t  | j|¡}|  	¡  |S )NFr   )
r'   ZUV_RUN_DEFAULTr^   r_   r:   r   rM   rK   r]   rJ   )r   ZnowaitÚonceÚmodeZ
ran_statusZran_callbacksÚresultr   r   r   ÚrunÈ  s"    
zloop.runc             C   s   t  | j¡}|d S )Ng     @@)r'   Zuv_nowr:   )r   Únowr   r   r   rw   í  s    zloop.nowc             C   s   t  | j¡ d S )N)r'   Zuv_update_timer:   )r   r   r   r   Ú
update_nowô  s    zloop.update_nowc             C   s"   | j rt | j ¡}|dkr|S d S )Nr   )r:   r'   Zuv_backend_fd)r   Úfdr   r   r   Úfileno÷  s    zloop.filenoc             C   sR   | j s
d S | jrd S t d¡| _t | j| j¡ | j| j_t 	| jtj
tj¡ d S )Nzuv_signal_t*)r-   Ú_sigchld_watcherr   rF   r'   Zuv_signal_initr:   rH   r   Zuv_signal_startr   ÚsignalÚSIGCHLD)r   r   r   r   Úinstall_sigchld   s    
zloop.install_sigchldc             C   s2   | j r| jsd S t | j¡ tj | j¡ | `d S )N)r-   r{   r'   Zuv_signal_stopr0   r$   Z_watcher_ffi_close)r   r   r   r   Úreset_sigchld  s
    zloop.reset_sigchldc             C   s†   x€yt  t j¡\}}}W n tk
r.   P Y nX |dkr:P | j |g ¡| j dg ¡ }x|D ]}|  |j||¡ q\W g | jd< qW d S )Nr   )r1   Úwait3ÚWNOHANGÚOSErrorr4   ÚgetZrun_callbackZ_set_waitpid_status)r   ÚpidZstatusZ_usageZchildren_watchersr$   r   r   r   r     s    
zloop._sigchld_callbackc             C   s   | j |j  |¡ d S )N)r4   r9   r>   )r   r$   r   r   r   Ú_register_child_watcher/  s    zloop._register_child_watcherc             C   sV   y| j |j  |¡ W n tk
r*   Y nX x$t| j ƒD ]}| j | s8| j |= q8W d S )N)r4   r9   ÚremoveÚ
ValueErrorr3   )r   r$   r„   r   r   r   Ú_unregister_child_watcher2  s    
zloop._unregister_child_watcherTc                sl   | j ‰yˆˆ  }|js"td| ƒ‚W n< tk
r`   | j | ˆ d¡}|ˆˆ < ‡ ‡fdd„|_Y nX | |¡S )Nz)IO Watcher %s unclosed but should be deadr   c                  s
   t ˆˆ ƒS )N)r   r   )ry   Úio_watchersr   r   Ú<lambda>N  s    zloop.io.<locals>.<lambda>)r6   Z_multiplex_watchersrV   ÚKeyErrorr0   ÚioZ_no_more_watchersZ	multiplex)r   ry   Zeventsrc   ÚpriorityZ
io_watcherr   )ry   r‰   r   rŒ   ?  s    zloop.ioc             C   s   t dƒ‚d S )Nzhprepare watchers are not currently supported in libuv. If you need them, please contact the maintainers.)Ú	TypeError)r   rc   r   r   r   r   ÚprepareR  s    zloop.prepare)NN)N)FF)TN)TN),r    r!   r"   Zapprox_timer_resolutionZerror_handlerZ_CHECK_POINTERZ_PREPARE_POINTERZ_PREPARE_CALLBACK_SIGZ_TIMER_POINTERr/   r   rA   rG   rI   rM   rP   rR   rT   rU   rX   rY   rZ   r`   rj   rc   rk   rl   rm   rK   rJ   rv   rw   rx   rz   r{   Z_sigchld_callback_ffir~   r   r   r…   rˆ   rŒ   r   Ú__classcell__r   r   )rN   r   r   O   sP   

!Y&!

%
r   )*Ú__doc__Z
__future__r   r   r1   Úcollectionsr   r   Úoperatorr   r|   Zgevent._ffir   Zgevent._ffi.loopr   Zgevent.libuvr	   r
   r   Zgevent._utilr   Zgevent._interfacesr   r   Úlibr'   Ú__all__r   rp   r#   ZGEVENT_CORE_EVENTSr$   r0   Z_events_to_strZUV_READABLEZREADZUV_WRITABLEZWRITEr+   r,   r.   r   r   r   r   r   Ú<module>   sB   
