B
    H/\8p                 @   s  d Z ddlmZmZ ddlmZ ddlZddl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gZG dd deZe  ZZG dd deZdddZejd dkreefZefZnddl Z e jfZee j!fZdZ"dZ#G dd deZ$dS )z0
Basic loop implementation for ffi-based cores.
    )absolute_importprint_function)dequeN)_dbg)GEVENT_DEBUG_LEVEL)TRACE)callback)PYPY)getswitchintervalAbstractLoopassign_standard_callbacksc               @   s   e Zd Zdd ZdS )_EVENTSTypec             C   s   dS )Nzgevent.core.EVENTS )selfr   r   /lib/python3.7/site-packages/gevent/_ffi/loop.py__repr__   s    z_EVENTSType.__repr__N)__name__
__module____qualname__r   r   r   r   r   r      s   r   c               @   sj   e Zd Zdd Zdd Zdd Zdd Zd	d
 Zdd Ze	sFdd Z
ndd Z
dd Zdd Zdd ZdS )AbstractCallbacksc             C   s    || _ g | _ttk r|j| _d S )N)ffi	callbacksr   r   from_handle)r   r   r   r   r   __init__F   s    zAbstractCallbacks.__init__c             C   s   | j |}|S )N)r   r   )r   handlexr   r   r   r   L   s    zAbstractCallbacks.from_handlec             C   s   d}yb|st d dS | |}|j}|j}|dkr8t}|rZ|d tkrZ|f|dd  }|j|  W nd   t d|t  y| W n t	k
r   | |}Y nX t |_
|jdk	r|jj| dS |jdk	r||jjkr|j|krdS dS dS )a  
        Returns an integer having one of three values:

        - -1
          An exception occurred during the callback and you must call
          :func:`_python_handle_error` to deal with it. The Python watcher
          object will have the exception tuple saved in ``_exc_info``.
        - 1
          Everything went according to plan. You should check to see if the libev
          watcher is still active, and call :func:`python_stop` if it is not. This will
          clean up the memory. Finding the watcher still active at the event loop level,
          but not having stopped itself at the gevent level is a buggy scenario and
          shouldn't happen.
        - 2
          Everything went according to plan, but the watcher has already
          been stopped. Its memory may no longer be valid.

        This function should never return 0, as that's the default value that
        Python exceptions will produce.
        Nzpython_callback got null handle   r   z+Got exception servicing watcher with handle   )r   r   Z_watcherargs_NOARGSGEVENT_CORE_EVENTSr   sysexc_infoUnboundLocalError	_exc_infoloop_keepalivesetadd)r   r   ZreventsZorig_ffi_watcherZthe_watcherr   r   r   r   python_callbackP   s8    




z!AbstractCallbacks.python_callbackc             C   sp   t d| |sd S z(| |}|j}|`|jjd|  W d y|  W n"   |jj|ft   Y nX d S )NzHandling error for handle)N)r   r   r%   r&   handle_errorstopr"   r#   )r   r   Z_reventswatcherr#   r   r   r   python_handle_error   s    

z%AbstractCallbacks.python_handle_errorc             C   sh   d }|d k	r|j jd nd }|r*| |}|d k	rH|jd ||| dS tdtjd t	||| d S )Nr   r   z0WARNING: gevent: Unhandled error with no watcher)file)
tb_framef_localsr   r&   r*   printr"   stderr	tracebackprint_exception)r   tvtbr,   r   r   r   r   unhandled_onerror   s    

z#AbstractCallbacks.unhandled_onerrorc             C   s,   |st dtjd d S | |}|  d S )NzWARNING: gevent: Unable to dereference handle; not stopping watcher. Native resources may leak. This is most likely a bug in gevent.)r.   )r1   r"   r2   r   r+   )r   r   r,   r   r   r   python_stop   s    

zAbstractCallbacks.python_stopc             C   s   d S )Nr   )r   watcher_ptrr   r   r   python_check_callback   s    z'AbstractCallbacks.python_check_callbackc             C   s$   y
t  W n t k
r   Y nX d S )N)MemoryError)r   r:   r   r   r   r;      s    
c             C   s,   |  |}|d kr td| d S |  d S )NzDWARNING: gevent: running prepare callbacks from a destroyed handle: )_find_loop_from_c_watcherr1   _run_callbacks)r   r:   r&   r   r   r   python_prepare_callback  s    
z)AbstractCallbacks.python_prepare_callbackc             C   sJ   |d k	r|j jd nd }|r&| |}|d k	rB|d ||| d S |d S )Nr:   )r/   r0   r=   r*   )r   r5   r6   r7   r:   r&   r   r   r   check_callback_onerror  s    
z(AbstractCallbacks.check_callback_onerrorc             C   s
   t  d S )N)NotImplementedError)r   r:   r   r   r   r=     s    z+AbstractCallbacks._find_loop_from_c_watcherN)r   r   r   r   r   r)   r-   r8   r9   r	   r;   r?   r@   r=   r   r   r   r   r   C   s   P 
	r   r   c                s   ||  t  fdd|D }xf jd f jd f jd f j jf j jff| D ].\}}|pd j}| j|d|} j	
| qTW  S )Nc                s   g | ]\}}t  ||fqS r   )getattr).0nameerror)r   r   r   
<listcomp>  s    z-assign_standard_callbacks.<locals>.<listcomp>)onerror)tupler)   r-   r9   r;   r@   r?   r8   Z
def_externr   append)r   libZcallbacks_classZextrasfuncZ
error_funcr   r   )r   r   r     s    

   2   c               @   s@  e Zd ZdZdZdZdZdZdZdZ	dvddZ
dwd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dd Zedd  Zed!d" Zed#d$ Zed%d& Zd'd( Zd)d* Zd+d, Zdxd-d.Z d/d0 Z!d1d2 Z"d3d4 Z#dyd5d6Z$d7d8 Z%d9d: Z&d;d< Z'd=d> Z(d?d@ Z)edAdB Z*edCdD Z+edEdF Z,edGdH Z-edIdJ Z.edKdL Z/dzdNdOZ0d{dQdRZ1d|dSdTZ2d}dUdVZ3d~dWdXZ4ddYdZZ5dd[d\Z6dd]d^Z7e7e8 d_< e9j:d`krddbdcZ;ddde Z<ddfdgZ=ddhdiZ>djdk Z?dldm Z@dndo ZAdpdq ZBdrds ZCedtdu ZDdS )r   NFc             C   sL   || _ || _d | _| j | | _|| _d| _t | _t	 | _
| || d S )NF)_ffiZ_lib_ptrZ
new_handle_handle_to_self	_watchersZ_in_callbackr   
_callbackssetr'   _init_loop_and_aux_watchers)r   r   rJ   Zwatchersflagsdefaultr   r   r   r   W  s    zAbstractLoop.__init__c             C   sx   |  ||| _| j| j| _| j| j_|   | j| j	| _
| j| j
_|   | j| j| _| j| j_|   d S )N)
_init_looprO   rN   new_CHECK_POINTERZ_checkrP   data_init_and_start_check_PREPARE_POINTERZ_prepare_init_and_start_prepare_TIMER_POINTERZ_timer0_init_callback_timer)r   rU   rV   r   r   r   rT   d  s    

	
z(AbstractLoop._init_loop_and_aux_watchersc             C   s
   t  dS )zs
        Called by __init__ to create or find the loop. The return value
        is assigned to self._ptr.
        N)rA   )r   rU   rV   r   r   r   rW     s    zAbstractLoop._init_loopc             C   s
   t  d S )N)rA   )r   r   r   r   r[     s    z"AbstractLoop._init_and_start_checkc             C   s
   t  d S )N)rA   )r   r   r   r   r]     s    z$AbstractLoop._init_and_start_preparec             C   s
   t  d S )N)rA   )r   r   r   r   r_     s    z!AbstractLoop._init_callback_timerc             C   s
   t  d S )N)rA   )r   r   r   r   _stop_callback_timer  s    z!AbstractLoop._stop_callback_timerc             C   s
   t  d S )N)rA   )r   r   r   r   _start_callback_timer  s    z"AbstractLoop._start_callback_timerc             C   s   |  d ||| d S )N)r*   )r   r5   r6   r7   r   r   r   _check_callback_handle_error  s    z)AbstractLoop._check_callback_handle_errorc             C   sH  d| _ z2t}|  }|t  }|   x| jr| j }|d8 }|   |j}d |_|j	}|d ks*|d krpq*zly||  W nZ   y| j
|ft   W n4   ytdtjd t  W n   Y nX Y nX Y nX W d d |_	X |dkr*| jr*t}|   |  |kr*d}P q*W |dkr(|   | jr8|   W d d| _ X d S )NTr   z&Exception while handling another error)r.   r   F)#starting_timer_may_update_loop_timeCALLBACK_CHECK_COUNTnowr
   r`   rR   popleftunrefr   r   r*   r"   r#   r1   r2   r3   	print_exc
update_nowra   )r   countre   Z
expirationcbr   r   r   r   r   r>     sL    



zAbstractLoop._run_callbacksc             C   s
   t  d S )N)rA   )r   r   r   r   _stop_aux_watchers  s    zAbstractLoop._stop_aux_watchersc             C   sL   | j rHz(| | j sdS |   | | j  W d d | _ | `| `| `X dS d S )NFT)rO   _can_destroy_looprl   _destroy_looprP   rR   r'   )r   r   r   r   destroy  s    zAbstractLoop.destroyc             C   s
   t  d S )N)rA   )r   ptrr   r   r   rm     s    zAbstractLoop._can_destroy_loopc             C   s
   t  d S )N)rA   )r   rp   r   r   r   rn   	  s    zAbstractLoop._destroy_loopc             C   s   | j S )N)rO   )r   r   r   r   rp     s    zAbstractLoop.ptrc             C   s   | j jS )N)rQ   r,   )r   r   r   r   WatcherType  s    zAbstractLoop.WatcherTypec             C   s   dS )Nr   r   )r   r   r   r   MAXPRI  s    zAbstractLoop.MAXPRIc             C   s   dS )Nr   r   )r   r   r   r   MINPRI  s    zAbstractLoop.MINPRIc             C   sb   yt |}W n   t  Y nX yd||f }W n   t  Y nX | d tt|d  d S )Nz%s: %s)osstrerrorr3   rh   r*   SystemError)r   messageerrnor   r   r   _handle_syserr  s    zAbstractLoop._handle_syserrc             C   sB   d }| j }|d k	r.t|d|}||||| n| |||| d S )Nr*   )error_handlerrB   _default_handle_error)r   contexttypevaluer7   r*   rz   r   r   r   r*   '  s    zAbstractLoop.handle_errorc             C   s   t ||| d S )N)r3   r4   )r   r|   r}   r~   r7   r   r   r   r{   1  s    z"AbstractLoop._default_handle_errorc             C   s
   t  d S )N)rA   )r   Znowaitoncer   r   r   run8  s    zAbstractLoop.runc             C   s
   t  d S )N)rA   )r   r   r   r   reinit;  s    zAbstractLoop.reinitc             C   s
   t  d S )N)rA   )r   r   r   r   ref>  s    zAbstractLoop.refc             C   s
   t  d S )N)rA   )r   r   r   r   rg   B  s    zAbstractLoop.unrefc             C   s
   t  d S )N)rA   )r   Zhowr   r   r   break_E  s    zAbstractLoop.break_c             C   s   d S )Nr   )r   r   r   r   verifyH  s    zAbstractLoop.verifyc             C   s
   t  d S )N)rA   )r   r   r   r   re   K  s    zAbstractLoop.nowc             C   s
   t  d S )N)rA   )r   r   r   r   ri   N  s    zAbstractLoop.update_nowc             C   s$   dd l }|jdtdd |   d S )Nr   z('update' is deprecated; use 'update_now'r   )
stacklevel)warningswarnDeprecationWarningri   )r   r   r   r   r   updateQ  s
    zAbstractLoop.updatec             C   s   d| j jt| |  f S )Nz<%s at 0x%x %s>)	__class__r   id_format)r   r   r   r   r   X  s    zAbstractLoop.__repr__c             C   s   | j r| jS dS )NF)rO   _default)r   r   r   r   rV   [  s    zAbstractLoop.defaultc             C   s   dS )Nr   r   )r   r   r   r   	iteration_  s    zAbstractLoop.iterationc             C   s   dS )Nr   r   )r   r   r   r   depthc  s    zAbstractLoop.depthc             C   s   dS )Nr   r   )r   r   r   r   backend_intg  s    zAbstractLoop.backend_intc             C   s   dS )NrV   r   )r   r   r   r   backendk  s    zAbstractLoop.backendc             C   s   dS )Nr   r   )r   r   r   r   
pendingcnto  s    zAbstractLoop.pendingcntTc             C   s   | j | ||||S )N)rQ   io)r   fdZeventsr   priorityr   r   r   r   s  s    zAbstractLoop.io        c             C   s   | j | ||||S )N)rQ   timer)r   Zafterrepeatr   r   r   r   r   r   v  s    zAbstractLoop.timerc             C   s   | j | |||S )N)rQ   signal)r   Zsignumr   r   r   r   r   r   y  s    zAbstractLoop.signalc             C   s   | j | ||S )N)rQ   idle)r   r   r   r   r   r   r   |  s    zAbstractLoop.idlec             C   s   | j | ||S )N)rQ   prepare)r   r   r   r   r   r   r     s    zAbstractLoop.preparec             C   s   | j | ||S )N)rQ   check)r   r   r   r   r   r   r     s    zAbstractLoop.checkc             C   s   | j | ||S )N)rQ   fork)r   r   r   r   r   r   r     s    zAbstractLoop.forkc             C   s   | j | ||S )N)rQ   async_)r   r   r   r   r   r   r     s    zAbstractLoop.async_asyncZwin32r   c             C   s   | j | |||S )N)rQ   child)r   pidZtracer   r   r   r   r     s    zAbstractLoop.childc             C   s   d S )Nr   )r   r   r   r   install_sigchld  s    zAbstractLoop.install_sigchldc             C   s   | j | ||||S )N)rQ   stat)r   pathZintervalr   r   r   r   r   r     s    zAbstractLoop.statc             C   s
   t | |S )N)r   )r   r   r   r   r   r     s    zAbstractLoop.callbackc             C   s
   t  d S )N)rA   )r   r   r   r   _setup_for_run_callback  s    z$AbstractLoop._setup_for_run_callbackc             G   s"   t ||}| j| |   |S )N)r   rR   rI   r   )r   rK   r   rk   r   r   r   run_callback  s    
zAbstractLoop.run_callbackc             C   s<   | j s
dS | j}| jr|d7 }|d| j 7 }||  7 }|S )NZ	destroyedz defaultz pending=%s)rO   r   rV   r   _format_details)r   msgr   r   r   r     s    zAbstractLoop._formatc             C   sd   d}|   }y
| j}W n tk
r.   d }Y nX |d k	rH|dt| 7 }|d k	r`|dt| 7 }|S )N z ref=z fileno=)fileno	activecntAttributeErrorrepr)r   r   r   r   r   r   r   r     s    

zAbstractLoop._format_detailsc             C   s   d S )Nr   )r   r   r   r   r     s    zAbstractLoop.filenoc             C   s   | j stddS )Nzoperation on destroyed loopr   )rO   
ValueError)r   r   r   r   r     s    zAbstractLoop.activecnt)NN)NN)FF)N)TN)r   TN)TN)TN)TN)TN)TN)TN)r   T)r   TN)N)Er   r   r   rz   rY   r^   Z_TIMER_CALLBACK_SIGr\   rc   r   r   rT   rW   r[   r]   r_   r`   ra   rb   r>   rl   ro   rm   rn   propertyrp   rq   rr   rs   ry   r*   r{   r   r   r   rg   r   r   re   ri   r   r   rV   r   r   r   r   r   r   r   r   r   r   r   r   r   localsr"   platformr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   E  s   

$P
















)r   )%__doc__Z
__future__r   r   collectionsr   r"   rt   r3   Zgevent._ffir   r   r   Zgevent._ffi.callbackr   Zgevent._compatr	   Zgeventr
   __all__objectr   ZEVENTSr!   r   r   version_infobytesstrZ
basestringintZinteger_typesZ__builtin__Zlongr    rd   r   r   r   r   r   <module>   s6   
% Z

