U
    Ã@ÛfÄD  ã                   @   s6  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ZeedƒrLdd„ ZeZn4zd dl	Z	e	j
ZW n  ek
r~   dd„ ZeZY nX d dlZd dlmZ d dlmZ zd d	lmZ W n  ek
rÐ   d d	lmZ Y nX d
ZdZdZdd„ ZG dd„ dƒZeed dd„ dd„ dƒZG dd„ deƒZdd„ ZG dd„ dƒZdS )é    NÚ	setitimerc                 C   s   t  t j| ¡ d S ©N)Úsignalr   ÚITIMER_REAL©Úseconds© r   úK/var/www/html/chatgpt/venv/lib/python3.8/site-packages/eventlet/hubs/hub.pyÚalarm_itimer
   s    r
   c                 C   s   t  t | ¡¡ d S r   )r   ÚalarmÚmathÚceilr   r   r   r	   Úalarm_signal   s    r   )Útimer)Ú	greenlets)Ú	monotonicTÚreadÚwritec                 C   s   dS )zP Used to de-fang a callback that may be triggered by a loop in BaseHub.wait
    Nr   )Úfilenor   r   r	   Úclosed_callback$   s    r   c                   @   s(   e Zd Zdd„ Zdd„ ZeZdd„ ZdS )Ú
FdListenerc                 C   sF   |t ks|tkst‚|| _|| _|| _|| _|| _d| _t	 
¡ | _	dS )aŠ   The following are required:
        cb - the standard callback, which will switch into the
            listening greenlet to indicate that the event waited upon
            is ready
        tb - a 'throwback'. This is typically greenlet.throw, used
            to raise a signal into the target greenlet indicating that
            an event was obsoleted by its underlying filehandle being
            repurposed.
        mark_as_closed - if any listener is obsoleted, this is called
            (in the context of some other client greenlet) to alert
            underlying filehandle-wrapping objects that they've been
            closed.
        FN)ÚREADÚWRITEÚAssertionErrorÚevtyper   ÚcbÚtbÚmark_as_closedÚspentÚgreenletÚ
getcurrent©Úselfr   r   r   r   r   r   r   r	   Ú__init__-   s    zFdListener.__init__c                 C   s    dt | ƒj| j| j| j| jf S )Nz%s(%r, %r, %r, %r))ÚtypeÚ__name__r   r   r   r   ©r"   r   r   r	   Ú__repr__D   s     ÿzFdListener.__repr__c                 C   s"   t | _| jd k	r|  ¡  d| _d S )NT)r   r   r   r   r&   r   r   r	   ÚdefangI   s    
zFdListener.defangN)r%   Ú
__module__Ú__qualname__r#   r'   Ú__str__r(   r   r   r   r	   r   +   s   r   c                 C   s   d S r   r   )Úxr   r   r	   Ú<lambda>P   ó    r-   c                       s(   e Zd Z‡ fdd„Zdd„ ZeZ‡  ZS )ÚDebugListenerc                    s,   t  ¡ | _t ¡ | _tƒ  |||||¡ d S r   )Ú	tracebackÚformat_stackÚwhere_calledr   r    Úsuperr#   r!   ©Ú	__class__r   r	   r#   X   s    

zDebugListener.__init__c              
   C   s*   d| j | j| j| j| j| jd | j¡f S )Nz:DebugListener(%r, %r, %r, %r, %r, %r)
%sEndDebugFdListenerÚ )r   r   r   r   r   r   Újoinr2   r&   r   r   r	   r'   ]   s    
ùzDebugListener.__repr__)r%   r)   r*   r#   r'   r+   Ú__classcell__r   r   r4   r	   r/   V   s   	r/   c                 C   s"   dd l }tdt| |¡ƒ ƒ‚d S )Nr   zBlocking detector ALARMED at)ÚinspectÚRuntimeErrorÚstrÚgetframeinfo)ÚsignumÚframer9   r   r   r	   Úalarm_handleri   s    r?   c                   @   s  e Zd ZdZeefZeZeZdBd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dCdd„Zdd „ Zd!d"„ Zd#d$„ ZdDd&d'„Zd(d)„ Zd*d+„ Zd,d-„ Zd.d/„ Zd0d1„ Zd2d3„ Z d4d5„ Z!d6d7„ Z"d8d9„ Z#d:d;„ Z$d<d=„ Z%d>d?„ Z&d@dA„ Z'dS )EÚBaseHubz Base hub class for easing the implementation of subclasses that are
    specific to a particular underlying event architecture. Nc                 C   s|   t i ti i| _t i ti i| _g | _|d kr.t}|| _t | j¡| _d| _	d| _
g | _g | _t| _d| _d| _d| _d| _d S )NFr   Té   )r   r   Ú	listenersÚsecondariesÚclosedr   Úclockr   ÚrunÚstoppingÚrunningÚtimersÚnext_timersr   ÚlclassÚtimers_canceledÚdebug_exceptionsÚdebug_blockingÚdebug_blocking_resolution)r"   rE   r   r   r	   r#   w   s     zBaseHub.__init__c                 C   s*   t   t jt¡}|tkr|| _t| jƒ d S r   )r   ÚSIGALRMr?   Ú_old_signal_handlerÚ	arm_alarmrO   )r"   Útmpr   r   r	   Úblock_detect_pre‹   s    zBaseHub.block_detect_prec                 C   s.   t | dƒr | jr t tj| j¡ t d¡ d S )NrQ   r   )ÚhasattrrQ   r   rP   r   r&   r   r   r	   Úblock_detect_post“   s
    
ÿzBaseHub.block_detect_postc                 C   sh   |   |||||¡}| j| }||kr\trBtd|||||| f ƒ‚| j|  |g ¡ |¡ n|||< |S )a–   Signals an intent to or write a particular file descriptor.

        The *evtype* argument is either the constant READ or WRITE.

        The *fileno* argument is the file number of the file of interest.

        The *cb* argument is the callback which will be called when the file
        is ready for reading/writing.

        The *tb* argument is the throwback used to signal (into the greenlet)
        that the file was closed.

        The *mark_as_closed* is used in the context of the event hub to
        prepare a Python object as being closed, pre-empting further
        close operations from accidentally shutting down the wrong OS thread.
        aP  Second simultaneous %s on fileno %s detected.  Unless you really know what you're doing, make sure that only one greenthread can %s any particular socket.  Consider using a pools.Pool. If you do know what you're doing and want to disable this error, call eventlet.debug.hub_prevent_multiple_readers(False) - MY THREAD=%s; THAT THREAD=%s)rK   rB   Úg_prevent_multiple_readersr:   rC   Ú
setdefaultÚappend)r"   r   r   r   r   r   ÚlistenerÚbucketr   r   r	   Úadd™   s"    
    ÿùÿzBaseHub.addc                 C   s–   d}| j  ¡ D ]<\}}||kr|| D ]}d}| j |¡ | ¡  q&||= q| j ¡ D ]:\}}||krV|| }d}| j |¡ |  |¡ | ¡  qV|S )zÀ We've received an indication that 'fileno' has been obsoleted.
            Any current listeners must be defanged, and notifications to
            their greenlets queued up to send.
        FT)rC   ÚitemsrD   rY   r(   rB   Úremove)r"   r   Úfoundr   r[   rZ   r   r   r	   Ú	_obsolete¾   s     


zBaseHub._obsoletec                 C   s   dS )zÈ We might want to do something when a fileno is closed.
            However, currently it suffices to obsolete listeners only
            when we detect an old fileno being recycled, on open.
        Nr   ©r"   r   r   r   r	   Únotify_closeØ   s    zBaseHub.notify_closec                 C   s¬   |j r
d S |j}|j}|| j| | krz| j| |= || j| kr¨| j| | }|rh| d¡| j| |< |s¨| j| |= n.| j| |  |¡ | j| | s¨| j| |= d S ©Nr   )r   r   r   rB   rC   Úpopr^   )r"   rZ   r   r   Úsecr   r   r	   r^   ß   s    zBaseHub.removec                 C   s   |   |¡ dS )zë If a file descriptor is returned by the OS as the result of some
            open call (or equivalent), that signals that it might be being
            recycled.

            Catch the case where the fd was previously in use.
        N)r`   ra   r   r   r	   Úmark_as_reopenedô   s    zBaseHub.mark_as_reopenedc              	   C   sì   g }|  | jt  |t¡¡ |  | jt  |t¡¡ | | jt  |d¡¡ | | jt  |d¡¡ |D ]6}z| |¡ W qh t	k
rœ   |  
t ¡ ¡ Y qhX qh| jt  |d¡ | jt  |d¡ | jt  |d¡ | jt  |d¡ dS )zQ Completely remove all listeners for this fileno.  For internal use
        only.r   N)rY   rB   r   ÚgetÚnoopr   ÚextendrC   r   Ú	ExceptionÚsquelch_generic_exceptionÚsysÚexc_inford   )r"   r   rB   rZ   r   r   r	   Úremove_descriptorý   s    zBaseHub.remove_descriptorc                 C   s,   | j  ¡ }|jjs(| tj tj	d¡¡ dS )zÑ Triggered from the main run loop. If a listener's underlying FD was
            closed somehow, throw an exception back to the trampoline, which should
            be able to manage it appropriately.
        zOperation on closed fileN)
rD   rd   r   Údeadr   ÚeventletZhubsZIOClosedÚerrnoÚENOTCONN)r"   rZ   r   r   r	   Ú	close_one  s    
zBaseHub.close_onec                 C   s,   | j jr(t   | j| j j¡}|| j _|| _ d S r   )r   ro   rF   Úparent)r"   Únewr   r   r	   Úensure_greenlet  s    zBaseHub.ensure_greenletc                 C   s”   t  ¡ }|| j k	stdƒ‚t|dd ƒ}|d k	rTz
|ƒ  W n   |  t ¡ ¡ Y nX |  ¡  z| j j|k	rr| j |_W n t	k
rˆ   Y nX | j  
¡ S )Nz'Cannot switch to MAINLOOP from MAINLOOPÚ
switch_out)r   r    r   Úgetattrrk   rl   rm   rv   rt   Ú
ValueErrorÚswitch)r"   Úcurrw   r   r   r	   rz   '  s    
zBaseHub.switchc              
   C   sx   t j|Ž  tj d|f ¡ tj ¡  z|  |¡ W n> tk
rr } z tj d|f ¡ tj ¡  W 5 d }~X Y nX d S )NzRemoving descriptor: %r
z(Exception while removing descriptor! %r
)r0   Úprint_exceptionrl   Ústderrr   Úflushrn   rj   )r"   r   rm   Úer   r   r	   Úsquelch_exception8  s    

zBaseHub.squelch_exceptionc                 C   s   t dƒ‚d S )NzImplement this in a subclass)ÚNotImplementedError)r"   r   r   r   r	   ÚwaitB  s    zBaseHub.waitc                 C   s   dS )Ng      N@r   r&   r   r   r	   Údefault_sleepE  s    zBaseHub.default_sleepc                 C   s   | j }|sd S |d d S rc   )rI   )r"   Útr   r   r	   Úsleep_untilH  s    zBaseHub.sleep_untilc                 O   sæ   | j rtdƒ‚zÄd| _ d| _| js²| jr2|  ¡  q"|  ¡  | jrH|  ¡  |  |  	¡ ¡ | jrd|  
¡  |  ¡  |  ¡ }|dkr†|  ¡ }n||  	¡  }|dkr¦|  |¡ q|  d¡ qd| _| jdd…= | jdd…= W 5 d| _ d| _X dS )z/Run the runloop until abort is called.
        zAlready running!FTNr   )rH   r:   rG   rD   rs   Úprepare_timersrN   rT   Úfire_timersrE   rV   r…   rƒ   r‚   rL   rI   rJ   )r"   ÚaÚkwZwakeup_whenZ
sleep_timer   r   r	   rF   N  s6    

zBaseHub.runFc                 C   sB   | j rd| _|r>| jt ¡ k	s&tdƒ‚|  ddd„ ¡ |  ¡  dS )am  Stop the runloop. If run is executing, it will exit after
        completing the next runloop iteration.

        Set *wait* to True to cause abort to switch to the hub immediately and
        wait until it's finished processing.  Waiting for the hub will only
        work from the main greenthread; all other greenthreads will become
        unreachable.
        Tz5Can't abort with wait from inside the hub's greenlet.r   c                   S   s   d S r   r   r   r   r   r	   r-   „  r.   zBaseHub.abort.<locals>.<lambda>N)rH   rG   r   r    r   Úschedule_call_globalrz   )r"   r‚   r   r   r	   Úabortu  s    	ÿzBaseHub.abortc                 C   s   | j rtj|Ž  tj ¡  d S r   ©rM   r0   r|   rl   r}   r~   )r"   rm   r   r   r	   rk   ‰  s    
z!BaseHub.squelch_generic_exceptionc                 C   s   | j rtj|Ž  tj ¡  d S r   rŒ   )r"   r   rm   r   r   r	   Úsquelch_timer_exceptionŽ  s    
zBaseHub.squelch_timer_exceptionc                 C   s"   |   ¡ |j }| j ||f¡ |S r   )rE   r   rJ   rY   )r"   r   Zscheduled_timer   r   r	   Ú	add_timer“  s    zBaseHub.add_timerc                 C   sr   |  j d7  _ t| jƒt| jƒ }|dkrn|d | j krnd| _ dd„ | jD ƒ| _dd„ | jD ƒ| _t | j¡ d S )NrA   iè  é   r   c                 S   s   g | ]}|d  j s|‘qS ©rA   ©Úcalled©Ú.0r„   r   r   r	   Ú
<listcomp>  s     
 z*BaseHub.timer_canceled.<locals>.<listcomp>c                 S   s   g | ]}|d  j s|‘qS r   r‘   r“   r   r   r	   r•   ž  s     
 )rL   ÚlenrI   rJ   ÚheapqÚheapify)r"   r   Z
len_timersr   r   r	   Útimer_canceled˜  s    zBaseHub.timer_canceledc                 C   sL   t j}| j}| jD ](}|d jr0|  jd8  _q|||ƒ q| jd d …= d S )NrA   )r—   ÚheappushrI   rJ   r’   rL   )r"   rš   r„   Úitemr   r   r	   r†   ¡  s    

zBaseHub.prepare_timersc                 O   s"   t j||f|ž|Ž}|  |¡ |S )az  Schedule a callable to be called after 'seconds' seconds have
        elapsed. Cancel the timer if greenlet has exited.
            seconds: The number of seconds to wait.
            cb: The callable to call after the given time.
            *args: Arguments to pass to the callable when called.
            **kw: Keyword arguments to pass to the callable when called.
        )r   Z
LocalTimerrŽ   ©r"   r   r   Úargsr‰   r„   r   r   r	   Úschedule_call_local«  s    
zBaseHub.schedule_call_localc                 O   s"   t j||f|ž|Ž}|  |¡ |S )a³  Schedule a callable to be called after 'seconds' seconds have
        elapsed. The timer will NOT be canceled if the current greenlet has
        exited before the timer fires.
            seconds: The number of seconds to wait.
            cb: The callable to call after the given time.
            *args: Arguments to pass to the callable when called.
            **kw: Keyword arguments to pass to the callable when called.
        )r   ÚTimerrŽ   rœ   r   r   r	   rŠ   ·  s    	
zBaseHub.schedule_call_globalc                 C   s”   | j }tj}|r|d }|d }|d }||k r2q||ƒ z |jrR|  jd8  _n|ƒ  W q | jk
rr   ‚ Y q   |  |t ¡ ¡ Y qX qd S )Nr   rA   )	rI   r—   Úheappopr’   rL   ÚSYSTEM_EXCEPTIONSr   rl   rm   )r"   Úwhenr„   r    ÚnextÚexpr   r   r   r	   r‡   Ä  s"    
zBaseHub.fire_timersc                 C   s   | j t  ¡ S r   )rB   r   Úvaluesr&   r   r   r	   Úget_readersß  s    zBaseHub.get_readersc                 C   s   | j t  ¡ S r   )rB   r   r¥   r&   r   r   r	   Úget_writersâ  s    zBaseHub.get_writersc                 C   s   t | jƒt | jƒ S r   )r–   rI   rJ   )Zhubr   r   r	   Úget_timers_countå  s    zBaseHub.get_timers_countc                 C   s   |rt | _nt| _d S r   )r/   rK   r   ©r"   Úvaluer   r   r	   Úset_debug_listenersè  s    zBaseHub.set_debug_listenersc                 C   s
   || _ d S r   )rM   r©   r   r   r	   Úset_timer_exceptionsî  s    zBaseHub.set_timer_exceptions)N)N)F)(r%   r)   r*   Ú__doc__ÚKeyboardInterruptÚ
SystemExitr¡   r   r   r#   rT   rV   r\   r`   rb   r^   rf   rn   rs   rv   rz   r€   r‚   rƒ   r…   rF   r‹   rk   r   rŽ   r™   r†   rž   rŠ   r‡   r¦   r§   r¨   r«   r¬   r   r   r   r	   r@   n   sF   
%	


'
	
r@   )rq   r—   r   r   rl   r0   rR   rU   r
   Zitimerr   ÚImportErrorr   Zeventlet.hubsrp   r   Zeventlet.supportr   r   r   ÚtimerW   r   r   r   r   rh   r/   r?   r@   r   r   r   r	   Ú<module>   s>   


%