a
    ið3e†  ã                   @   sä  d Z 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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
l
mZ ddl
mZ ddl
mZ ddlmZ ddlmZ g d¢Zejdkrêedƒ‚dd„ ZG dd„ dejƒZeedƒrdd„ ZnddlZdd„ ZG dd„ dej ƒZ!G dd„ dej"ej#ƒZ$eedƒrfej%Z&nddlZdd „ Z&G d!d"„ d"ej'ƒZ(G d#d$„ d$ƒZ)G d%d&„ d&e)ƒZ*G d'd(„ d(e*ƒZ+G d)d*„ d*e*ƒZ,G d+d,„ d,ej-ƒZ.eZ/e.Z0dS )-z2Selector event loop for Unix with signal handling.é    Né   )Úbase_events)Úbase_subprocess)Ú	constants)Ú
coroutines)Úevents)Úfutures)Úselector_events)Ú	selectors)Ú
transports)Ú	coroutine)Úlogger)ÚSelectorEventLoopÚAbstractChildWatcherÚSafeChildWatcherÚFastChildWatcherÚDefaultEventLoopPolicyÚwin32z+Signals are not really supported on Windowsc                 C   s   dS )zDummy signal handler.N© )ÚsignumÚframer   r   úF/home/pi/bot/my_env/lib/python3.9/site-packages/asyncio/unix_events.pyÚ_sighandler_noop$   s    r   c                       s¶   e Zd ZdZd"‡ fd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d„Zd$dd„Zed%dd„ƒZdd„ Zeddddœdd„ƒZed&ddddœd d!„ƒZ‡  ZS )'Ú_UnixSelectorEventLoopzdUnix event loop.

    Adds signal handling and UNIX Domain Socket support to SelectorEventLoop.
    Nc                    s   t ƒ  |¡ i | _d S ©N)ÚsuperÚ__init__Ú_signal_handlers)ÚselfÚselector©Ú	__class__r   r   r   /   s    z_UnixSelectorEventLoop.__init__c                 C   s   t  ¡ S r   )ÚsocketÚ
socketpair©r   r   r   r   Ú_socketpair3   s    z"_UnixSelectorEventLoop._socketpairc                    s(   t ƒ  ¡  t| jƒD ]}|  |¡ qd S r   )r   ÚcloseÚlistr   Úremove_signal_handler©r   Úsigr    r   r   r&   6   s    
z_UnixSelectorEventLoop.closec                 C   s   |D ]}|sq|   |¡ qd S r   )Ú_handle_signal)r   Údatar   r   r   r   Ú_process_self_data;   s    z)_UnixSelectorEventLoop._process_self_datac                 G   sN  t  |¡st  |¡rtdƒ‚|  |¡ |  ¡  zt | j 	¡ ¡ W n4 t
tfyv } ztt|ƒƒ‚W Y d}~n
d}~0 0 t ||| ¡}|| j|< zt |t¡ t |d¡ W nœ tyH } z‚| j|= | jszt d¡ W n6 t
tfy } zt d|¡ W Y d}~n
d}~0 0 |jtjkr2td |¡ƒ‚n‚ W Y d}~n
d}~0 0 dS )zÃAdd a handler for a signal.  UNIX only.

        Raise ValueError if the signal number is invalid or uncatchable.
        Raise RuntimeError if there is a problem setting up the handler.
        z3coroutines cannot be used with add_signal_handler()NFéÿÿÿÿúset_wakeup_fd(-1) failed: %súsig {} cannot be caught)r   ÚiscoroutineÚiscoroutinefunctionÚ	TypeErrorÚ_check_signalZ_check_closedÚsignalÚset_wakeup_fdZ_csockÚfilenoÚ
ValueErrorÚOSErrorÚRuntimeErrorÚstrr   ÚHandler   r   Úsiginterruptr   ÚinfoÚerrnoÚEINVALÚformat)r   r*   ÚcallbackÚargsÚexcÚhandleZnexcr   r   r   Úadd_signal_handlerB   s2    
ÿ
"
"z)_UnixSelectorEventLoop.add_signal_handlerc                 C   s8   | j  |¡}|du rdS |jr*|  |¡ n
|  |¡ dS )z2Internal helper that is the actual signal handler.N)r   ÚgetZ
_cancelledr(   Z_add_callback_signalsafe)r   r*   rE   r   r   r   r+   o   s    z%_UnixSelectorEventLoop._handle_signalc              
   C   sæ   |   |¡ z| j|= W n ty*   Y dS 0 |tjkr>tj}ntj}zt ||¡ W nB ty– } z*|jtj	kr€t
d |¡ƒ‚n‚ W Y d}~n
d}~0 0 | jsâzt d¡ W n4 ttfyà } zt d|¡ W Y d}~n
d}~0 0 dS )zwRemove a handler for a signal.  UNIX only.

        Return True if a signal handler was removed, False if not.
        Fr0   Nr.   r/   T)r4   r   ÚKeyErrorr5   ÚSIGINTÚdefault_int_handlerÚSIG_DFLr9   r?   r@   r:   rA   r6   r8   r   r>   )r   r*   ÚhandlerrD   r   r   r   r(   y   s(    

"z,_UnixSelectorEventLoop.remove_signal_handlerc                 C   sF   t |tƒstd |¡ƒ‚d|  kr.tjk sBn td |tj¡ƒ‚dS )zÁInternal helper to validate a signal.

        Raise ValueError if the signal number is invalid or uncatchable.
        Raise RuntimeError if there is a problem setting up the handler.
        zsig must be an int, not {!r}r   zsig {} out of range(1, {})N)Ú
isinstanceÚintr3   rA   r5   ÚNSIGr8   r)   r   r   r   r4   ™   s    
ÿz$_UnixSelectorEventLoop._check_signalc                 C   s   t | ||||ƒS r   )Ú_UnixReadPipeTransport©r   ÚpipeÚprotocolÚwaiterÚextrar   r   r   Ú_make_read_pipe_transport¦   s    z0_UnixSelectorEventLoop._make_read_pipe_transportc                 C   s   t | ||||ƒS r   )Ú_UnixWritePipeTransportrQ   r   r   r   Ú_make_write_pipe_transportª   s    z1_UnixSelectorEventLoop._make_write_pipe_transportc	                 k   sÎ   t  ¡ ²}
tj| d}t| |||||||f||dœ|	¤Ž}|
 | ¡ | j|¡ z|E d H  W n( ty„ } z|}W Y d }~nd }~0 0 d }|d ur¬| 	¡  | 
¡ E d H  |‚W d   ƒ n1 sÀ0    Y  |S )N)Úloop)rT   rU   )r   Úget_child_watcherr   ZFutureÚ_UnixSubprocessTransportÚadd_child_handlerZget_pidÚ_child_watcher_callbackÚ	Exceptionr&   Ú_wait)r   rS   rC   ÚshellÚstdinÚstdoutÚstderrÚbufsizerU   ÚkwargsÚwatcherrT   ÚtransprD   Úerrr   r   r   Ú_make_subprocess_transport®   s,    

ÿþý
ÿ"z1_UnixSelectorEventLoop._make_subprocess_transportc                 C   s   |   |j|¡ d S r   )Zcall_soon_threadsafeZ_process_exited)r   ÚpidÚ
returncoderg   r   r   r   r]   Ì   s    z._UnixSelectorEventLoop._child_watcher_callback)ÚsslÚsockÚserver_hostnamec                c   sÜ   |d u st |tƒsJ ‚|r,|d u r<tdƒ‚n|d ur<tdƒ‚|d ur |d urTtdƒ‚t tjtjd¡}z | d¡ |  ||¡E d H  W qº   | ¡  ‚ Y qº0 n|d u r°tdƒ‚| d¡ |  	||||¡E d H \}}||fS )Nz/you have to pass server_hostname when using sslz+server_hostname is only meaningful with sslú3path and sock can not be specified at the same timer   Fzno path and sock were specified)
rM   r;   r8   r"   ÚAF_UNIXÚSOCK_STREAMÚsetblockingZsock_connectr&   Z_create_connection_transport)r   Úprotocol_factoryÚpathrl   rm   rn   Ú	transportrS   r   r   r   Úcreate_unix_connectionÏ   s6    ÿÿ


ÿz-_UnixSelectorEventLoop.create_unix_connectionéd   )rm   Úbacklogrl   c          	   
   C   s  t |tƒrtdƒ‚|d ur´|d ur*tdƒ‚t tjtj¡}z| |¡ W qÞ tyœ } z<| 	¡  |j
t
jkr†d |¡}tt
j|ƒd ‚n‚ W Y d }~qÞd }~0    | 	¡  ‚ Y qÞ0 n*|d u rÄtdƒ‚|jtjkrÞtd |¡ƒ‚t | |g¡}| |¡ | d¡ |  ||||¡ |S )Nz*ssl argument must be an SSLContext or Nonero   zAddress {!r} is already in usez-path was not specified, and no sock specifiedz+A UNIX Domain Socket was expected, got {!r}F)rM   Úboolr3   r8   r"   rp   rq   Úbindr9   r&   r?   Z
EADDRINUSErA   Úfamilyr   ÚServerÚlistenrr   Z_start_serving)	r   rs   rt   rm   rx   rl   rD   ÚmsgÚserverr   r   r   Úcreate_unix_serverò   s@    
ÿ

ÿÿ

z)_UnixSelectorEventLoop.create_unix_server)N)NN)NN)N)N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r%   r&   r-   rF   r+   r(   r4   rV   rX   r   ri   r]   rv   r€   Ú__classcell__r   r   r    r   r   )   s6   -
   ÿ
  ÿ
 þþ"ÿr   Úset_blockingc                 C   s   t  | d¡ d S )NF)Úosr†   )Úfdr   r   r   Ú_set_nonblocking  s    r‰   c                 C   s,   t   | t j¡}|tjB }t   | t j|¡ d S r   )ÚfcntlZF_GETFLr‡   Ú
O_NONBLOCKZF_SETFL)rˆ   Úflagsr   r   r   r‰   #  s    
c                       sv   e Zd ZdZd‡ fdd„	Zdd„ Zdd„ Zd	d
„ Zdd„ Zdd„ Z	e
jdkrTdd„ Zddd„Zdd„ Zdd„ Z‡  ZS )rP   i   Nc                    s¼   t ƒ  |¡ || jd< || _|| _| ¡ | _t | j¡j	}t
 |¡s`t
 |¡s`t
 |¡s`tdƒ‚t| jƒ || _d| _| j | jj| ¡ | j | jj| j| j¡ |d ur¸| j |jd ¡ d S )NrR   z)Pipe transport is for pipes/sockets only.F)r   r   Ú_extraÚ_loopÚ_piper7   Ú_filenor‡   ÚfstatÚst_modeÚstatÚS_ISFIFOÚS_ISSOCKÚS_ISCHRr8   r‰   Ú	_protocolÚ_closingÚ	call_soonÚconnection_madeÚ
add_readerÚ_read_readyÚ_set_result_unless_cancelled)r   rY   rR   rS   rT   rU   Úmoder    r   r   r   -  s*    


ÿþ
ÿz_UnixReadPipeTransport.__init__c                 C   s”   | j jg}| jd u r | d¡ n| jr0| d¡ | d| j ¡ | jd ur|t | jj	| jt
j¡}|rp| d¡ q†| d¡ n
| d¡ dd |¡ S )NÚclosedÚclosingúfd=%sÚpollingÚidleú<%s>ú )r!   r   r   Úappendr˜   r   r	   Ú_test_selector_eventrŽ   Ú	_selectorr
   Ú
EVENT_READÚjoin)r   r>   r¢   r   r   r   Ú__repr__C  s     



þ
z_UnixReadPipeTransport.__repr__c              
   C   sº   zt  | j| j¡}W nD ttfy*   Y nŒ tyX } z|  |d¡ W Y d }~nfd }~0 0 |rl| j 	|¡ nJ| j
 ¡ r‚t d| ¡ d| _| j
 | j¡ | j
 | jj¡ | j
 | jd ¡ d S )Nz"Fatal read error on pipe transportú%r was closed by peerT)r‡   Úreadr   Úmax_sizeÚBlockingIOErrorÚInterruptedErrorr9   Ú_fatal_errorr—   Zdata_receivedrŽ   Ú	get_debugr   r>   r˜   Úremove_readerr™   Zeof_receivedÚ_call_connection_lost)r   r,   rD   r   r   r   rœ   V  s    "
z"_UnixReadPipeTransport._read_readyc                 C   s   | j  | j¡ d S r   )rŽ   r³   r   r$   r   r   r   Úpause_readingh  s    z$_UnixReadPipeTransport.pause_readingc                 C   s   | j  | j| j¡ d S r   )rŽ   r›   r   rœ   r$   r   r   r   Úresume_readingk  s    z%_UnixReadPipeTransport.resume_readingc                 C   s   | j s|  d ¡ d S r   )r˜   Ú_closer$   r   r   r   r&   n  s    z_UnixReadPipeTransport.close©é   é   c                 C   s(   | j d ur$t d|  t¡ | j  ¡  d S ©Nzunclosed transport %r©r   ÚwarningsÚwarnÚResourceWarningr&   r$   r   r   r   Ú__del__v  s    
z_UnixReadPipeTransport.__del__úFatal error on pipe transportc                 C   sZ   t |tƒr4|jtjkr4| j ¡ rLtjd| |dd n| j ||| | j	dœ¡ |  
|¡ d S ©Nz%r: %sT©Úexc_info)ÚmessageÚ	exceptionru   rS   )rM   r9   r?   ZEIOrŽ   r²   r   ÚdebugÚcall_exception_handlerr—   r·   ©r   rD   rÅ   r   r   r   r±   {  s    
üz#_UnixReadPipeTransport._fatal_errorc                 C   s(   d| _ | j | j¡ | j | j|¡ d S ©NT)r˜   rŽ   r³   r   r™   r´   ©r   rD   r   r   r   r·   ‰  s    z_UnixReadPipeTransport._closec                 C   sP   z,| j  |¡ W | j ¡  d | _d | _ d | _n| j ¡  d | _d | _ d | _0 d S r   ©r—   Zconnection_lostr   r&   rŽ   rË   r   r   r   r´   Ž  s    
ý
z,_UnixReadPipeTransport._call_connection_lost)NN)rÁ   )r   r‚   rƒ   r®   r   r«   rœ   rµ   r¶   r&   ÚsysÚversion_inforÀ   r±   r·   r´   r…   r   r   r    r   rP   )  s   

rP   c                       s”   e Zd Zd ‡ 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ejdkrhdd„ Zdd„ Zd!dd„Zd"dd„Zdd„ Z‡  ZS )#rW   Nc                    sØ   t ƒ  ||¡ || jd< || _| ¡ | _t | j¡j}t	 
|¡}|s`t	 |¡s`t	 |¡s`tdƒ‚t| jƒ || _g | _d| _d| _| j | jj| ¡ |s¤tj d¡s¼| j | jj| j| j¡ |d urÔ| j |jd ¡ d S )NrR   z?Pipe transport is only for pipes, sockets and character devicesr   FÚaix)r   r   r   r   r7   r   r‡   r‘   r’   r“   r•   r”   r–   r8   r‰   r—   Ú_bufferÚ
_conn_lostr˜   rŽ   r™   rš   rÍ   ÚplatformÚ
startswithr›   rœ   r   )r   rY   rR   rS   rT   rU   rž   Ú	is_socketr    r   r   r   ›  s0    


ÿþ
ÿz _UnixWritePipeTransport.__init__c                 C   sª   | j jg}| jd u r | d¡ n| jr0| d¡ | d| j ¡ | jd ur’t | jj	| jt
j¡}|rp| d¡ n
| d¡ |  ¡ }| d| ¡ n
| d¡ dd |¡ S )	NrŸ   r    r¡   r¢   r£   z
bufsize=%sr¤   r¥   )r!   r   r   r¦   r˜   r   r	   r§   rŽ   r¨   r
   ÚEVENT_WRITEÚget_write_buffer_sizerª   )r   r>   r¢   rd   r   r   r   r«   »  s$    



þ

z _UnixWritePipeTransport.__repr__c                 C   s   t dd„ | jD ƒƒS )Nc                 s   s   | ]}t |ƒV  qd S r   )Úlen)Ú.0r,   r   r   r   Ú	<genexpr>Ò  ó    z@_UnixWritePipeTransport.get_write_buffer_size.<locals>.<genexpr>)ÚsumrÐ   r$   r   r   r   rÖ   Ñ  s    z-_UnixWritePipeTransport.get_write_buffer_sizec                 C   s6   | j  ¡ rt d| ¡ | jr*|  tƒ ¡ n|  ¡  d S )Nr¬   )rŽ   r²   r   r>   rÐ   r·   ÚBrokenPipeErrorr$   r   r   r   rœ   Ô  s
    
z#_UnixWritePipeTransport._read_readyc              
   C   s.  t |tttfƒsJ t|ƒƒ‚t |tƒr.t|ƒ}|s6d S | jsB| jrj| jtjkrXt	 
d¡ |  jd7  _d S | jszt | j|¡}W nX ttfyž   d}Y n@ tyÜ } z(|  jd7  _|  |d¡ W Y d }~d S d }~0 0 |t|ƒkrîd S |dkr||d … }| j | j| j¡ | j |¡ |  ¡  d S )Nz=pipe closed by peer or os.write(pipe, data) raised exception.r   r   ú#Fatal write error on pipe transport)rM   ÚbytesÚ	bytearrayÚ
memoryviewÚreprrÑ   r˜   r   Z!LOG_THRESHOLD_FOR_CONNLOST_WRITESr   ÚwarningrÐ   r‡   Úwriter   r¯   r°   r^   r±   r×   rŽ   Z
add_writerÚ_write_readyr¦   Z_maybe_pause_protocol©r   r,   ÚnrD   r   r   r   rã   Ý  s4    


z_UnixWritePipeTransport.writec              
   C   s  d  | j¡}|sJ dƒ‚| j ¡  zt | j|¡}W nl ttfyV   | j |¡ Y n¸ t	y  } z4|  j
d7  _
| j | j¡ |  |d¡ W Y d }~nvd }~0 0 |t|ƒkrì| j | j¡ |  ¡  | jsè| jrè| j | j¡ |  d ¡ d S |dkr||d … }| j |¡ d S )NrÚ   zData should not be emptyr   rÝ   r   )rª   rÐ   Úclearr‡   rã   r   r¯   r°   r¦   r^   rÑ   rŽ   Úremove_writerr±   r×   Z_maybe_resume_protocolr˜   r³   r´   rå   r   r   r   rä   þ  s*    
"

z$_UnixWritePipeTransport._write_readyc                 C   s   dS rÊ   r   r$   r   r   r   Úcan_write_eof  s    z%_UnixWritePipeTransport.can_write_eofc                 C   sB   | j r
d S | jsJ ‚d| _ | js>| j | j¡ | j | jd ¡ d S rÊ   )r˜   r   rÐ   rŽ   r³   r   r™   r´   r$   r   r   r   Ú	write_eof  s    
z!_UnixWritePipeTransport.write_eofc                 C   s   | j d ur| js|  ¡  d S r   )r   r˜   rê   r$   r   r   r   r&   &  s    z_UnixWritePipeTransport.closer¸   c                 C   s(   | j d ur$t d|  t¡ | j  ¡  d S r»   r¼   r$   r   r   r   rÀ   /  s    
z_UnixWritePipeTransport.__del__c                 C   s   |   d ¡ d S r   )r·   r$   r   r   r   Úabort4  s    z_UnixWritePipeTransport.abortrÁ   c                 C   sR   t |ttfƒr,| j ¡ rDtjd| |dd n| j ||| | jdœ¡ |  	|¡ d S rÂ   )
rM   rÜ   ÚConnectionResetErrorrŽ   r²   r   rÇ   rÈ   r—   r·   rÉ   r   r   r   r±   7  s    
üz$_UnixWritePipeTransport._fatal_errorc                 C   sF   d| _ | jr| j | j¡ | j ¡  | j | j¡ | j | j|¡ d S rÊ   )	r˜   rÐ   rŽ   rè   r   rç   r³   r™   r´   rË   r   r   r   r·   E  s    
z_UnixWritePipeTransport._closec                 C   sP   z,| j  |¡ W | j ¡  d | _d | _ d | _n| j ¡  d | _d | _ d | _0 d S r   rÌ   rË   r   r   r   r´   M  s    
ý
z-_UnixWritePipeTransport._call_connection_lost)NN)rÁ   )N)r   r‚   rƒ   r   r«   rÖ   rœ   rã   rä   ré   rê   r&   rÍ   rÎ   rÀ   rë   r±   r·   r´   r…   r   r   r    r   rW   ˜  s    	!	


rW   Úset_inheritablec                 C   sN   t tddƒ}t | tj¡}|s4t | tj||B ¡ nt | tj|| @ ¡ d S )NZ
FD_CLOEXECr   )ÚgetattrrŠ   ZF_GETFDZF_SETFD)rˆ   ÚinheritableZcloexec_flagÚoldr   r   r   Ú_set_inheritable]  s
    rñ   c                   @   s   e Zd Zdd„ ZdS )r[   c           	   	   K   sv   d }|t jkr*| j ¡ \}}t| ¡ dƒ t j|f||||d|dœ|¤Ž| _|d urr| ¡  t	| 
¡ d|d| j_d S )NF)r`   ra   rb   rc   Úuniversal_newlinesrd   Úwb)Ú	buffering)Ú
subprocessÚPIPErŽ   r%   rñ   r7   ÚPopenÚ_procr&   ÚopenÚdetachra   )	r   rC   r`   ra   rb   rc   rd   re   Zstdin_wr   r   r   Ú_starti  s    
ÿþþz_UnixSubprocessTransport._startN)r   r‚   rƒ   rû   r   r   r   r   r[   g  s   r[   c                   @   s@   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ Zdd„ Z	dS )r   aH  Abstract base class for monitoring child processes.

    Objects derived from this class monitor a collection of subprocesses and
    report their termination or interruption by a signal.

    New callbacks are registered with .add_child_handler(). Starting a new
    process must be done within a 'with' block to allow the watcher to suspend
    its activity until the new process if fully registered (this is needed to
    prevent a race condition in some implementations).

    Example:
        with watcher:
            proc = subprocess.Popen("sleep 1")
            watcher.add_child_handler(proc.pid, callback)

    Notes:
        Implementations of this class must be thread-safe.

        Since child watcher objects may catch the SIGCHLD signal and call
        waitpid(-1), there should be only one active object per process.
    c                 G   s
   t ƒ ‚dS )a  Register a new child handler.

        Arrange for callback(pid, returncode, *args) to be called when
        process 'pid' terminates. Specifying another callback for the same
        process replaces the previous handler.

        Note: callback() must be thread-safe.
        N©ÚNotImplementedError©r   rj   rB   rC   r   r   r   r\   —  s    	z&AbstractChildWatcher.add_child_handlerc                 C   s
   t ƒ ‚dS )z Removes the handler for process 'pid'.

        The function returns True if the handler was successfully removed,
        False if there was nothing to remove.Nrü   ©r   rj   r   r   r   Úremove_child_handler¢  s    z)AbstractChildWatcher.remove_child_handlerc                 C   s
   t ƒ ‚dS )zÔAttach the watcher to an event loop.

        If the watcher was previously attached to an event loop, then it is
        first detached before attaching to the new loop.

        Note: loop may be None.
        Nrü   ©r   rY   r   r   r   Úattach_loopª  s    z AbstractChildWatcher.attach_loopc                 C   s
   t ƒ ‚dS )zlClose the watcher.

        This must be called to make sure that any underlying resource is freed.
        Nrü   r$   r   r   r   r&   ´  s    zAbstractChildWatcher.closec                 C   s
   t ƒ ‚dS )zdEnter the watcher's context and allow starting new processes

        This function must return selfNrü   r$   r   r   r   Ú	__enter__»  s    zAbstractChildWatcher.__enter__c                 C   s
   t ƒ ‚dS )zExit the watcher's contextNrü   ©r   ÚaÚbÚcr   r   r   Ú__exit__Á  s    zAbstractChildWatcher.__exit__N)
r   r‚   rƒ   r„   r\   r   r  r&   r  r  r   r   r   r   r   €  s   
r   c                   @   sD   e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zd	d
„ Zdd„ Zdd„ Z	dS )ÚBaseChildWatcherc                 C   s
   d | _ d S r   )rŽ   r$   r   r   r   r   È  s    zBaseChildWatcher.__init__c                 C   s   |   d ¡ d S r   )r  r$   r   r   r   r&   Ë  s    zBaseChildWatcher.closec                 C   s
   t ƒ ‚d S r   rü   )r   Úexpected_pidr   r   r   Ú_do_waitpidÎ  s    zBaseChildWatcher._do_waitpidc                 C   s
   t ƒ ‚d S r   rü   r$   r   r   r   Ú_do_waitpid_allÑ  s    z BaseChildWatcher._do_waitpid_allc                 C   sZ   |d u st |tjƒsJ ‚| jd ur0| j tj¡ || _|d urV| tj| j¡ |  	¡  d S r   )
rM   r   ZAbstractEventLooprŽ   r(   r5   ÚSIGCHLDrF   Ú	_sig_chldr  r  r   r   r   r  Ô  s    
zBaseChildWatcher.attach_loopc              
   C   sH   z|   ¡  W n6 tyB } z| j d|dœ¡ W Y d }~n
d }~0 0 d S )Nz$Unknown exception in SIGCHLD handler)rÅ   rÆ   )r  r^   rŽ   rÈ   rË   r   r   r   r  â  s    þzBaseChildWatcher._sig_chldc                 C   s2   t  |¡rt  |¡ S t  |¡r*t  |¡S |S d S r   )r‡   ÚWIFSIGNALEDÚWTERMSIGÚ	WIFEXITEDÚWEXITSTATUS)r   Ústatusr   r   r   Ú_compute_returncodeî  s
    


z$BaseChildWatcher._compute_returncodeN)
r   r‚   rƒ   r   r&   r  r  r  r  r  r   r   r   r   r	  Æ  s   r	  c                       s\   e Zd ZdZ‡ f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‡  ZS )r   ad  'Safe' child watcher implementation.

    This implementation avoids disrupting other code spawning processes by
    polling explicitly each process in the SIGCHLD handler instead of calling
    os.waitpid(-1).

    This is a safe solution but it has a significant overhead when handling a
    big number of children (O(n) each time SIGCHLD is raised)
    c                    s   t ƒ  ¡  i | _d S r   )r   r   Ú
_callbacksr$   r    r   r   r     s    
zSafeChildWatcher.__init__c                    s   | j  ¡  tƒ  ¡  d S r   )r  rç   r   r&   r$   r    r   r   r&     s    
zSafeChildWatcher.closec                 C   s   | S r   r   r$   r   r   r   r    s    zSafeChildWatcher.__enter__c                 C   s   d S r   r   r  r   r   r   r    s    zSafeChildWatcher.__exit__c                 G   s   ||f| j |< |  |¡ d S r   )r  r  rþ   r   r   r   r\     s    z"SafeChildWatcher.add_child_handlerc                 C   s(   z| j |= W dS  ty"   Y dS 0 d S ©NTF©r  rH   rÿ   r   r   r   r     s
    z%SafeChildWatcher.remove_child_handlerc                 C   s   t | jƒD ]}|  |¡ q
d S r   )r'   r  r  rÿ   r   r   r   r  "  s    z SafeChildWatcher._do_waitpid_allc                 C   sÐ   |dksJ ‚zt  |t j¡\}}W n& tyH   |}d}t d|¡ Y n00 |dkrVd S |  |¡}| j ¡ rxt 	d||¡ z| j
 |¡\}}W n, ty¸   | j ¡ r´tjd|dd Y n0 |||g|¢R Ž  d S )Nr   éÿ   z8Unknown child process pid %d, will report returncode 255ú$process %s exited with returncode %sz'Child watcher got an unexpected pid: %rTrÃ   )r‡   ÚwaitpidÚWNOHANGÚChildProcessErrorr   râ   r  rŽ   r²   rÇ   r  ÚpoprH   )r   r
  rj   r  rk   rB   rC   r   r   r   r  '  s2    þ


ÿ
ÿzSafeChildWatcher._do_waitpid)r   r‚   rƒ   r„   r   r&   r  r  r\   r   r  r  r…   r   r   r    r   r   ü  s   
r   c                       sT   e Zd ZdZ‡ fdd„Z‡ fdd„Zdd„ Zdd	„ Zd
d„ Zdd„ Z	dd„ Z
‡  ZS )r   aW  'Fast' child watcher implementation.

    This implementation reaps every terminated processes by calling
    os.waitpid(-1) directly, possibly breaking other code spawning processes
    and waiting for their termination.

    There is no noticeable overhead when handling a big number of children
    (O(1) each time a child terminates).
    c                    s*   t ƒ  ¡  i | _t ¡ | _i | _d| _d S )Nr   )r   r   r  Ú	threadingÚLockÚ_lockÚ_zombiesÚ_forksr$   r    r   r   r   T  s
    

zFastChildWatcher.__init__c                    s"   | j  ¡  | j ¡  tƒ  ¡  d S r   )r  rç   r!  r   r&   r$   r    r   r   r&   [  s    

zFastChildWatcher.closec                 C   s<   | j " |  jd7  _| W  d   ƒ S 1 s.0    Y  d S )Nr   )r   r"  r$   r   r   r   r  `  s    zFastChildWatcher.__enter__c                 C   st   | j N |  jd8  _| js"| js2W d   ƒ d S t| jƒ}| j ¡  W d   ƒ n1 sZ0    Y  t d|¡ d S )Nr   z5Caught subprocesses termination from unknown pids: %s)r   r"  r!  r;   rç   r   râ   )r   r  r  r  Zcollateral_victimsr   r   r   r  f  s    
(þzFastChildWatcher.__exit__c              	   G   sŠ   | j sJ dƒ‚| jP z| j |¡}W n. tyT   ||f| j|< Y W d   ƒ d S 0 W d   ƒ n1 sj0    Y  |||g|¢R Ž  d S )NzMust use the context manager)r"  r   r!  r  rH   r  )r   rj   rB   rC   rk   r   r   r   r\   t  s    2z"FastChildWatcher.add_child_handlerc                 C   s(   z| j |= W dS  ty"   Y dS 0 d S r  r  rÿ   r   r   r   r     s
    z%FastChildWatcher.remove_child_handlerc              	   C   s  zt  dt j¡\}}W n ty*   Y d S 0 |dkr8d S |  |¡}| jŒ z| j |¡\}}W nN ty¬   | j	r¤|| j
|< | j ¡ r”t d||¡ Y W d   ƒ q d }Y n0 | j ¡ rÆt d||¡ W d   ƒ n1 sÚ0    Y  |d u  rþt d||¡ q |||g|¢R Ž  q d S )Nr.   r   z,unknown process %s exited with returncode %sr  z8Caught subprocess termination from unknown pid: %d -> %d)r‡   r  r  r  r  r   r  r  rH   r"  r!  rŽ   r²   r   rÇ   râ   )r   rj   r  rk   rB   rC   r   r   r   r  ˆ  s:    


þ

ÿ"
þz FastChildWatcher._do_waitpid_all)r   r‚   rƒ   r„   r   r&   r  r  r\   r   r  r…   r   r   r    r   r   J  s   	r   c                       sH   e Zd ZdZeZ‡ fdd„Zdd„ Z‡ fdd„Zdd	„ Z	d
d„ Z
‡  ZS )Ú_UnixDefaultEventLoopPolicyz:UNIX event loop policy with a watcher for child processes.c                    s   t ƒ  ¡  d | _d S r   )r   r   Ú_watcherr$   r    r   r   r   ·  s    
z$_UnixDefaultEventLoopPolicy.__init__c                 C   s\   t jB | jd u r:tƒ | _tt ¡ tjƒr:| j | j	j
¡ W d   ƒ n1 sN0    Y  d S r   )r   r   r$  r   rM   r  Úcurrent_threadÚ_MainThreadr  Ú_localrŽ   r$   r   r   r   Ú_init_watcher»  s    
ÿz)_UnixDefaultEventLoopPolicy._init_watcherc                    s6   t ƒ  |¡ | jdur2tt ¡ tjƒr2| j |¡ dS )zÑSet the event loop.

        As a side effect, if a child watcher was set before, then calling
        .set_event_loop() from the main thread will call .attach_loop(loop) on
        the child watcher.
        N)r   Úset_event_loopr$  rM   r  r%  r&  r  r  r    r   r   r)  Ã  s
    
ÿz*_UnixDefaultEventLoopPolicy.set_event_loopc                 C   s   | j du r|  ¡  | j S )zzGet the watcher for child processes.

        If not yet set, a SafeChildWatcher object is automatically created.
        N)r$  r(  r$   r   r   r   rZ   Ñ  s    
z-_UnixDefaultEventLoopPolicy.get_child_watcherc                 C   s4   |du st |tƒsJ ‚| jdur*| j ¡  || _dS )z$Set the watcher for child processes.N)rM   r   r$  r&   )r   rf   r   r   r   Úset_child_watcherÛ  s    

z-_UnixDefaultEventLoopPolicy.set_child_watcher)r   r‚   rƒ   r„   r   Z_loop_factoryr   r(  r)  rZ   r*  r…   r   r   r    r   r#  ³  s   
r#  )1r„   r?   r‡   r5   r"   r“   rõ   rÍ   r  r½   Ú r   r   r   r   r   r   r	   r
   r   r   Úlogr   Ú__all__rÒ   ÚImportErrorr   ZBaseSelectorEventLoopr   Úhasattrr‰   rŠ   ZReadTransportrP   Z_FlowControlMixinZWriteTransportrW   rí   rñ   ZBaseSubprocessTransportr[   r   r	  r   r   ZBaseDefaultEventLoopPolicyr#  r   r   r   r   r   r   Ú<module>   s^   
 u
oÿ @
F6Ni2