U
    wy]Ǿ                     @   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
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 dZe
jdkreddd ZG dd dejZG dd dej Z!G dd dej"ej#Z$G dd dej%Z&G dd dZ'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'Z,G d(d) d)e'Z-G d*d+ d+ej.Z/eZ0e/Z1dS ),z2Selector event loop for Unix with signal handling.    N   )base_events)base_subprocess)	constants)
coroutines)events)
exceptions)futures)selector_events)tasks)
transports)logger)SelectorEventLoopAbstractChildWatcherSafeChildWatcherFastChildWatcherMultiLoopChildWatcherThreadedChildWatcherDefaultEventLoopPolicywin32z+Signals are not really supported on Windowsc                 C   s   dS )zDummy signal handler.N )signumframer   r   P/home/stadmin/Documents/SimTableSoftware/Python-3.8.0/Lib/asyncio/unix_events.py_sighandler_noop*   s    r   c                       s   e Zd ZdZd) 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dZd+ddZd,ddZdd Zd-dddddddZd.dddddddd Zd!d" Zd#d$ Zd%d& Z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   5   s    z_UnixSelectorEventLoop.__init__c                    sZ   t    t s.t| jD ]}| | qn(| jrVtjd| dt	| d | j
  d S )NzClosing the loop z@ on interpreter shutdown stage, skipping signal handlers removalsource)r   closesysis_finalizinglistr   remove_signal_handlerwarningswarnResourceWarningclearr    sigr"   r   r   r&   9   s    
z_UnixSelectorEventLoop.closec                 C   s   |D ]}|sq|  | qd S r   )_handle_signal)r    datar   r   r   r   _process_self_dataG   s    z)_UnixSelectorEventLoop._process_self_datac                 G   sL  t |st |rtd| | |   zt| j	  W n2 t
tfk
rt } ztt|W 5 d}~X Y nX t||| d}|| j|< zt|t t|d W n tk
rF } zz| j|= | jsztd W n4 t
tfk
r } ztd| W 5 d}~X Y nX |jtjkr4td| dn W 5 d}~X Y nX dS )zAdd 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_signal_check_closedsignalset_wakeup_fdZ_csockfileno
ValueErrorOSErrorRuntimeErrorstrr   Handler   r   siginterruptr   infoerrnoEINVAL)r    r0   callbackargsexchandleZnexcr   r   r   add_signal_handlerN   s2    


z)_UnixSelectorEventLoop.add_signal_handlerc                 C   s8   | j |}|dkrdS |jr*| | n
| | dS )z2Internal helper that is the actual signal handler.N)r   get
_cancelledr*   _add_callback_signalsafe)r    r0   rL   r   r   r   r1   {   s    z%_UnixSelectorEventLoop._handle_signalc              
   C   s   |  | z| j|= W n tk
r,   Y dS X |tjkr@tj}ntj}zt|| W nB tk
r } z$|jtj	krt
d| dn W 5 d}~X Y nX | jsztd W n2 ttfk
r } ztd| W 5 d}~X Y nX dS )zwRemove a handler for a signal.  UNIX only.

        Return True if a signal handler was removed, False if not.
        Fr6   r7   Nr4   r5   T)r;   r   KeyErrorr=   SIGINTdefault_int_handlerSIG_DFLrA   rG   rH   rB   r>   r@   r   rF   )r    r0   handlerrK   r   r   r   r*      s(    

z,_UnixSelectorEventLoop.remove_signal_handlerc                 C   s6   t |tstd||t kr2td| dS )zInternal 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 zinvalid signal number N)
isinstanceintr:   r=   valid_signalsr@   r/   r   r   r   r;      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   )_UnixWritePipeTransportrZ   r   r   r   _make_write_pipe_transport   s    z1_UnixSelectorEventLoop._make_write_pipe_transportc	              
      s   t  }
|
 std|  }t| |||||||f||d|	}|
| | j| z|I d H  W nD t	t
fk
r    Y n, tk
r   |  | I d H   Y nX W 5 Q R X |S )NzRasyncio.get_child_watcher() is not activated, subprocess support is not installed.)r]   r^   )r   get_child_watcher	is_activerB   create_future_UnixSubprocessTransportadd_child_handlerget_pid_child_watcher_callback
SystemExitKeyboardInterruptBaseExceptionr&   _wait)r    r\   rJ   shellstdinstdoutstderrbufsizer^   kwargswatcherr]   transpr   r   r   _make_subprocess_transport   s8    

    
 z1_UnixSelectorEventLoop._make_subprocess_transportc                 C   s   |  |j| d S r   )call_soon_threadsafe_process_exited)r    pid
returncodert   r   r   r   rh      s    z._UnixSelectorEventLoop._child_watcher_callback)sslsockserver_hostnamessl_handshake_timeoutc          	         s   |d kst |tst|r,|d krLtdn |d k	r<td|d k	rLtd|d k	r|d k	rdtdt|}ttjtjd}z |	d | 
||I d H  W q   |   Y qX n@|d krtd|jtjks|jtjkrtd||	d | j|||||d	I d H \}}||fS )
Nz/you have to pass server_hostname when using sslz+server_hostname is only meaningful with ssl1ssl_handshake_timeout is only meaningful with ssl3path and sock can not be specified at the same timer   Fzno path and sock were specified.A UNIX Domain Stream Socket was expected, got )r}   )rV   rC   AssertionErrorr@   osfspathsocketAF_UNIXSOCK_STREAMsetblockingsock_connectr&   familytype_create_connection_transport)	r    protocol_factorypathrz   r{   r|   r}   	transportr\   r   r   r   create_unix_connection   sT    




   z-_UnixSelectorEventLoop.create_unix_connectiond   T)r{   backlogrz   r}   start_servingc             
      s  t |trtd|d k	r&|s&td|d k	rH|d k	r@tdt|}ttjtj}|d dkrz t	
t	|jrt| W nB tk
r   Y n0 tk
r } ztd|| W 5 d }~X Y nX z|| W nl tk
r0 }	 z8|  |	jtjkrd|d}
ttj|
d n W 5 d }	~	X Y n   |   Y nX n<|d krZtd	|jtjksv|jtjkrtd
||d t| |g||||}|r|  tjd| dI d H  |S )Nz*ssl argument must be an SSLContext or Noner~   r   r   )r    z2Unable to check or remove stale UNIX socket %r: %rzAddress z is already in usez-path was not specified, and no sock specifiedr   F)loop)rV   boolr:   r@   r   r   r   r   r   statS_ISSOCKst_moderemoveFileNotFoundErrorrA   r   errorbindr&   rG   Z
EADDRINUSEr   r   r   r   Server_start_servingr   sleep)r    r   r   r{   r   rz   r}   r   errrK   msgserverr   r   r   create_unix_server  sn    


 



  z)_UnixSelectorEventLoop.create_unix_serverc              
      s   z
t j W n, tk
r6 } ztdW 5 d }~X Y nX z| }W n2 ttjfk
rv } ztdW 5 d }~X Y nX zt |j	}W n, t
k
r } ztdW 5 d }~X Y nX |r|n|}	|	sdS |  }
| |
d |||||	d |
I d H S )Nzos.sendfile() is not availableznot a regular filer   )r   sendfileAttributeErrorr   SendfileNotAvailableErrorr?   ioUnsupportedOperationfstatst_sizerA   rd   _sock_sendfile_native_impl)r    r{   fileoffsetcountrK   r?   r   fsize	blocksizefutr   r   r   _sock_sendfile_nativeJ  s2    
   z,_UnixSelectorEventLoop._sock_sendfile_nativec	                 C   s,  |  }	|d k	r| | | r4| ||| d S |rd|| }|dkrd| ||| || d S zt|	|||}
W nD ttfk
r   |d kr| 	|| | 
|	| j||	||||||
 Y nb tk
rj } z|d k	r|jtjkrt|tk	rtdtj}||_|}|dkrBtd}| ||| || n| ||| || W 5 d }~X Y n ttfk
r    Y n tk
r } z| ||| || W 5 d }~X Y njX |
dkr| ||| || nD||
7 }||
7 }|d kr
| 	|| | 
|	| j||	||||||
 d S )Nr   zsocket is not connectedzos.sendfile call failed)r?   remove_writer	cancelled_sock_sendfile_update_filepos
set_resultr   r   BlockingIOErrorInterruptedError_sock_add_cancellation_callback
add_writerr   rA   rG   ENOTCONNr   ConnectionError	__cause__r   r   set_exceptionri   rj   rk   )r    r   Zregistered_fdr{   r?   r   r   r   
total_sentfdsentrK   new_excr   r   r   r   r   a  s    

     



 


     z1_UnixSelectorEventLoop._sock_sendfile_native_implc                 C   s   |dkrt ||t j d S Nr   )r   lseekSEEK_SET)r    r?   r   r   r   r   r   r     s    z4_UnixSelectorEventLoop._sock_sendfile_update_fileposc                    s    fdd}| | d S )Nc                    s&   |   r" }|dkr" | d S )Nr4   )r   r?   r   )r   r   r    r{   r   r   cb  s    zB_UnixSelectorEventLoop._sock_add_cancellation_callback.<locals>.cb)add_done_callback)r    r   r{   r   r   r   r   r     s    z6_UnixSelectorEventLoop._sock_add_cancellation_callback)N)NN)NN)N)N)N)__name__
__module____qualname____doc__r   r&   r3   rM   r1   r*   r;   r_   ra   ru   rh   r   r   r   r   r   r   __classcell__r   r   r"   r   r   /   sH   -
   
  
 
  .   CFr   c                       s   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	dd Z
dd Zdd ZejfddZdddZdd Zdd Z  ZS ) rY   i   Nc                    s   t  | || jd< || _|| _| | _|| _d| _d| _	t
| jj}t|st|st|sd | _d | _d | _tdt
| jd | j| jj|  | j| jj| j| j |d k	r| jtj|d  d S )Nr[   Fz)Pipe transport is for pipes/sockets only.)r   r   _extra_loop_piper?   _fileno	_protocol_closing_pausedr   r   r   r   S_ISFIFOr   S_ISCHRr@   set_blocking	call_soonconnection_made_add_reader_read_readyr	   _set_result_unless_cancelled)r    r   r[   r\   r]   r^   moder"   r   r   r     s:    


 
 z_UnixReadPipeTransport.__init__c                 C   s   | j jg}| jd kr |d n| jr0|d |d| j  t| jdd }| jd k	r|d k	rt	|| jt
j}|r|d q|d n | jd k	r|d n
|d dd	|S )
Nclosedclosingfd=	_selectorpollingidleopen<{}> )r#   r   r   appendr   r   getattrr   r
   _test_selector_event	selectors
EVENT_READformatjoin)r    rF   r!   r   r   r   r   __repr__  s(    


  

z_UnixReadPipeTransport.__repr__c              
   C   s   zt | j| j}W nD ttfk
r,   Y n tk
rX } z| |d W 5 d }~X Y n^X |rl| j	| nJ| j
 rt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_sizer   r   rA   _fatal_errorr   data_receivedr   	get_debugr   rF   r   _remove_readerr   eof_received_call_connection_lost)r    r2   rK   r   r   r   r     s    
z"_UnixReadPipeTransport._read_readyc                 C   s>   | j s| jrd S d| _| j| j | j r:td|  d S )NTz%r pauses reading)r   r   r   r   r   r   r   debugr    r   r   r   pause_reading  s    
z$_UnixReadPipeTransport.pause_readingc                 C   sB   | j s| jsd S d| _| j| j| j | j r>td|  d S )NFz%r resumes reading)	r   r   r   r   r   r   r   r   r   r   r   r   r   resume_reading  s    
z%_UnixReadPipeTransport.resume_readingc                 C   s
   || _ d S r   r   r    r\   r   r   r   set_protocol  s    z#_UnixReadPipeTransport.set_protocolc                 C   s   | j S r   r   r   r   r   r   get_protocol  s    z#_UnixReadPipeTransport.get_protocolc                 C   s   | j S r   r   r   r   r   r   
is_closing  s    z!_UnixReadPipeTransport.is_closingc                 C   s   | j s| d  d S r   )r   _closer   r   r   r   r&     s    z_UnixReadPipeTransport.closec                 C   s,   | j d k	r(|d| t| d | j   d S Nzunclosed transport r$   r   r-   r&   r    _warnr   r   r   __del__  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	exceptionr   r\   )rV   rA   rG   ZEIOr   r   r   r   call_exception_handlerr   r  r    rK   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    rK   r   r   r   r  -  s    z_UnixReadPipeTransport._closec                 C   s4   z| j| W 5 | j   d | _ d | _d | _X d S r   r   r&   r   r   connection_lostr  r   r   r   r   2  s    
z,_UnixReadPipeTransport._call_connection_lost)NN)r  )r   r   r   r   r   r   r   r   r   r   r   r  r&   r+   r,   r  r   r  r   r   r   r   r"   r   rY     s   
rY   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dd Zdd Zdd ZejfddZdd Zd&dd Zd'd!d"Zd#d$ Z  ZS )(r`   Nc           
         s   t  || || jd< || _| | _|| _t | _d| _	d| _
t| jj}t|}t|}t|}	|s|s|	sd | _d | _d | _tdt| jd | j| jj|  |	s|rtjds| j| jj| j| j |d k	r| jtj|d  d S )Nr[   r   Fz?Pipe transport is only for pipes, sockets and character devicesaix)r   r   r   r   r?   r   r   	bytearray_buffer
_conn_lostr   r   r   r   r   r   r   r   r@   r   r   r   r   r'   platform
startswithr   r   r	   r   )
r    r   r[   r\   r]   r^   r   Zis_charZis_fifoZ	is_socketr"   r   r   r   ?  s:    




 
 z _UnixWritePipeTransport.__init__c                 C   s   | j jg}| jd kr |d n| jr0|d |d| j  t| jdd }| jd k	r|d k	rt	|| jt
j}|r|d n
|d |  }|d|  n | jd k	r|d n
|d d	d
|S )Nr   r   r   r   r   r   zbufsize=r   r   r   )r#   r   r   r   r   r   r   r   r
   r   r   EVENT_WRITEget_write_buffer_sizer   r   )r    rF   r!   r   rq   r   r   r   r   d  s,    


  


z _UnixWritePipeTransport.__repr__c                 C   s
   t | jS r   )lenr  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   rF   r  r  BrokenPipeErrorr   r   r   r   r     s
    
z#_UnixWritePipeTransport._read_readyc              
   C   sR  t |tttfstt|t |tr.t|}|s6d S | jsB| jrj| jtj	krXt
d |  jd7  _d S | js8zt| j|}W nt ttfk
r   d}Y nZ ttfk
r    Y nB tk
r } z$|  jd7  _| |d W Y d S d }~X Y nX |t|krd S |dkr&t||d  }| j| j| j |  j|7  _|   d S )Nz=pipe closed by peer or os.write(pipe, data) raised exception.r   r   #Fatal write error on pipe transport)rV   bytesr  
memoryviewr   reprr  r   r   !LOG_THRESHOLD_FOR_CONNLOST_WRITESr   warningr  r   writer   r   r   ri   rj   rk   r   r  r   Z_add_writer_write_ready_maybe_pause_protocol)r    r2   nrK   r   r   r   r$    s8    


z_UnixWritePipeTransport.writec              
   C   s  | j stdzt| j| j }W n ttfk
r:   Y n ttfk
rR    Y n t	k
r } z6| j 
  |  jd7  _| j| j | |d W 5 d }~X Y nhX |t| j kr| j 
  | j| j |   | jr| j| j | d  d S |dkr| j d |= d S )NzData should not be emptyr   r  r   )r  r   r   r$  r   r   r   ri   rj   rk   r.   r  r   _remove_writerr   r  _maybe_resume_protocolr   r   r   )r    r'  rK   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td| _ | js>| j| j | j| jd  d S r  )	r   r   r   r  r   r   r   r   r   r   r   r   r   	write_eof  s    
z!_UnixWritePipeTransport.write_eofc                 C   s
   || _ d S r   r   r   r   r   r   r     s    z$_UnixWritePipeTransport.set_protocolc                 C   s   | j S r   r   r   r   r   r   r     s    z$_UnixWritePipeTransport.get_protocolc                 C   s   | j S r   r   r   r   r   r   r    s    z"_UnixWritePipeTransport.is_closingc                 C   s   | j d k	r| js|   d S r   )r   r   r+  r   r   r   r   r&     s    z_UnixWritePipeTransport.closec                 C   s,   | j d k	r(|d| t| d | 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   abort  s    z_UnixWritePipeTransport.abortr  c                 C   sN   t |tr(| j r@tjd| |dd n| j||| | jd | | d S r	  )	rV   rA   r   r   r   r   r  r   r  r  r   r   r   r     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    s    
z_UnixWritePipeTransport._closec                 C   s4   z| j| W 5 | j   d | _ d | _d | _X d S r   r  r  r   r   r   r     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   r   r"   r   r`   <  s"   %	#	

r`   c                   @   s   e Zd Zdd ZdS )re   c           	   	   K   s   d }|t jkrt \}}zPt j|f||||d|d|| _|d k	rh|  t| d|d| j_	d }W 5 |d k	r|  |  X d S )NF)rm   rn   ro   rp   universal_newlinesrq   wb)	buffering)

subprocessPIPEr   
socketpairr&   Popen_procr   detachrn   )	r    rJ   rm   rn   ro   rp   rq   rr   Zstdin_wr   r   r   _start  s.    
    z_UnixSubprocessTransport._startN)r   r   r   r6  r   r   r   r   re   	  s   re   c                   @   sH   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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    rx   rI   rJ   r   r   r   rf   9  s    	z&AbstractChildWatcher.add_child_handlerc                 C   s
   t  dS )zRemoves the handler for process 'pid'.

        The function returns True if the handler was successfully removed,
        False if there was nothing to remove.Nr7  r    rx   r   r   r   remove_child_handlerD  s    z)AbstractChildWatcher.remove_child_handlerc                 C   s
   t  dS )zAttach 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.
        Nr7  r    r   r   r   r   attach_loopL  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.
        Nr7  r   r   r   r   r&   V  s    zAbstractChildWatcher.closec                 C   s
   t  dS )zReturn ``True`` if the watcher is active and is used by the event loop.

        Return True if the watcher is installed and ready to handle process exit
        notifications.

        Nr7  r   r   r   r   rc   ]  s    zAbstractChildWatcher.is_activec                 C   s
   t  dS )zdEnter the watcher's context and allow starting new processes

        This function must return selfNr7  r   r   r   r   	__enter__f  s    zAbstractChildWatcher.__enter__c                 C   s
   t  dS )zExit the watcher's contextNr7  r    abcr   r   r   __exit__l  s    zAbstractChildWatcher.__exit__N)r   r   r   r   rf   r;  r=  r&   rc   r>  rC  r   r   r   r   r   "  s   
	r   c                 C   s2   t | rt |  S t | r*t | S | S d S r   )r   WIFSIGNALEDWTERMSIG	WIFEXITEDWEXITSTATUS)statusr   r   r   _compute_returncodeq  s
    


rI  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 | _ i | _d S r   )r   
_callbacksr   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   | j d k	o| j  S r   )r   
is_runningr   r   r   r   rc     s    zBaseChildWatcher.is_activec                 C   s
   t  d S r   r7  )r    expected_pidr   r   r   _do_waitpid  s    zBaseChildWatcher._do_waitpidc                 C   s
   t  d S r   r7  r   r   r   r   _do_waitpid_all  s    z BaseChildWatcher._do_waitpid_allc                 C   s~   |d kst |tjst| jd k	r<|d kr<| jr<tdt | jd k	rT| j	t
j || _|d k	rz|t
j| j |   d S )NzCA loop is being detached from a child watcher with pending handlers)rV   r   AbstractEventLoopr   r   rK  r+   r,   RuntimeWarningr*   r=   SIGCHLDrM   	_sig_chldrO  r<  r   r   r   r=    s    
zBaseChildWatcher.attach_loopc              
   C   s^   z|    W nL ttfk
r&    Y n4 tk
rX } z| jd|d W 5 d }~X Y nX d S )N$Unknown exception in SIGCHLD handler)r  r  )rO  ri   rj   rk   r   r  r  r   r   r   rS    s    zBaseChildWatcher._sig_chldN)
r   r   r   r   r&   rc   rN  rO  r=  rS  r   r   r   r   rJ    s   rJ  c                       sP   e Zd Z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   | j   t   d S r   )rK  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   rC    s    zSafeChildWatcher.__exit__c                 G   s   ||f| j |< | | d S r   )rK  rN  r9  r   r   r   rf     s    z"SafeChildWatcher.add_child_handlerc                 C   s*   z| j |= W dS  tk
r$   Y dS X d S NTFrK  rQ   r:  r   r   r   r;    s
    z%SafeChildWatcher.remove_child_handlerc                 C   s   t | jD ]}| | q
d S r   r)   rK  rN  r:  r   r   r   rO    s    z SafeChildWatcher._do_waitpid_allc                 C   s   |dkst zt|tj\}}W n( tk
rJ   |}d}td| Y n.X |dkrXd S t|}| j	 rxt
d|| z| j|\}}W n. tk
r   | j	 rtjd|dd Y nX |||f|  d S )Nr      8Unknown child process pid %d, will report returncode 255$process %s exited with returncode %s'Child watcher got an unexpected pid: %rTr
  )r   r   waitpidWNOHANGChildProcessErrorr   r#  rI  r   r   r   rK  poprQ   )r    rM  rx   rH  ry   rI   rJ   r   r   r   rN    s6    

 
 zSafeChildWatcher._do_waitpid)r   r   r   r   r&   r>  rC  rf   r;  rO  rN  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    t | _i | _d| _d S r   )r   r   	threadingLock_lock_zombies_forksr   r"   r   r   r     s    

zFastChildWatcher.__init__c                    s"   | j   | j  t   d S r   )rK  r.   rc  r   r&   r   r"   r   r   r&     s    

zFastChildWatcher.closec              
   C   s0   | j   |  jd7  _| W  5 Q R  S Q R X d S )Nr   )rb  rd  r   r   r   r   r>    s    zFastChildWatcher.__enter__c              	   C   s^   | j B |  jd8  _| js"| js0W 5 Q R  d S t| j}| j  W 5 Q R X td| d S )Nr   z5Caught subprocesses termination from unknown pids: %s)rb  rd  rc  rC   r.   r   r#  )r    r@  rA  rB  Zcollateral_victimsr   r   r   rC    s    
zFastChildWatcher.__exit__c              	   G   st   | j std| jF z| j|}W n. tk
rT   ||f| j|< Y W 5 Q R  d S X W 5 Q R X |||f|  d S )NzMust use the context manager)rd  r   rb  rc  r_  rQ   rK  )r    rx   rI   rJ   ry   r   r   r   rf   '  s    z"FastChildWatcher.add_child_handlerc                 C   s*   z| j |= W dS  tk
r$   Y dS X d S rU  rV  r:  r   r   r   r;  5  s
    z%FastChildWatcher.remove_child_handlerc              	   C   s   zt dt j\}}W n tk
r,   Y d S X |dkr:d S t|}| j z| j|\}}W nN tk
r   | j	r|| j
|< | j rtd|| Y W 5 Q R  q d }Y nX | j rtd|| W 5 Q R X |d krtd|| q |||f|  q d S )Nr4   r   z,unknown process %s exited with returncode %srZ  z8Caught subprocess termination from unknown pid: %d -> %d)r   r\  r]  r^  rI  rb  rK  r_  rQ   rd  rc  r   r   r   r   r#  )r    rx   rH  ry   rI   rJ   r   r   r   rO  <  s@    

 

  z FastChildWatcher._do_waitpid_all)r   r   r   r   r   r&   r>  rC  rf   r;  rO  r   r   r   r"   r   r     s   	r   c                   @   sh   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d Z
dd Zdd Zdd Zdd ZdS )r   a~  A watcher that doesn't require running loop in the main thread.

    This implementation registers a SIGCHLD signal handler on
    instantiation (which may conflict with other code that
    install own handler for this signal).

    The solution is safe but it has a significant overhead when
    handling a big number of processes (*O(n)* each time a
    SIGCHLD is received).
    c                 C   s   i | _ d | _d S r   )rK  _saved_sighandlerr   r   r   r   r   z  s    zMultiLoopChildWatcher.__init__c                 C   s
   | j d k	S r   )re  r   r   r   r   rc   ~  s    zMultiLoopChildWatcher.is_activec                 C   sP   | j   | jd k	rLttj}|| jkr6td nttj| j d | _d S )Nz+SIGCHLD handler was changed by outside code)	rK  r.   re  r=   	getsignalrR  rS  r   r#  )r    rU   r   r   r   r&     s    


zMultiLoopChildWatcher.closec                 C   s   | S r   r   r   r   r   r   r>    s    zMultiLoopChildWatcher.__enter__c                 C   s   d S r   r   r    exc_typeexc_valexc_tbr   r   r   rC    s    zMultiLoopChildWatcher.__exit__c                 G   s&   t  }|||f| j|< | | d S r   )r   get_running_looprK  rN  )r    rx   rI   rJ   r   r   r   r   rf     s    z'MultiLoopChildWatcher.add_child_handlerc                 C   s*   z| j |= W dS  tk
r$   Y dS X d S rU  rV  r:  r   r   r   r;    s
    z*MultiLoopChildWatcher.remove_child_handlerc                 C   sJ   | j d krFttj| j| _ | j d kr8td tj| _ ttjd d S )NzaPrevious SIGCHLD handler was set by non-Python code, restore to default handler on watcher close.F)re  r=   rR  rS  r   r#  rT   rE   r<  r   r   r   r=    s    


z!MultiLoopChildWatcher.attach_loopc                 C   s   t | jD ]}| | q
d S r   rW  r:  r   r   r   rO    s    z%MultiLoopChildWatcher._do_waitpid_allc           	      C   s   |dkst zt|tj\}}W n, tk
rN   |}d}td| d}Y nX |dkr\d S t|}d}z| j	|\}}}W n$ t
k
r   tjd|dd Y nHX | rtd|| n.|r| rtd	|| |j|||f|  d S )
Nr   rX  rY  FTr[  r
  %Loop %r that handles pid %r is closedrZ  )r   r   r\  r]  r^  r   r#  rI  rK  r_  rQ   	is_closedr   r   rv   )	r    rM  rx   rH  ry   	debug_logr   rI   rJ   r   r   r   rN    s<    
  z!MultiLoopChildWatcher._do_waitpidc              	   C   sL   z|    W n: ttfk
r&    Y n" tk
rF   tjddd Y nX d S )NrT  Tr
  )rO  ri   rj   rk   r   r#  )r    r   r   r   r   r   rS    s    zMultiLoopChildWatcher._sig_chldN)r   r   r   r   r   rc   r&   r>  rC  rf   r;  r=  rO  rN  rS  r   r   r   r   r   g  s   
%r   c                   @   sf   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Ze	j
fddZdd Zdd Zdd Zdd ZdS )r   aA  Threaded child watcher implementation.

    The watcher uses a thread per process
    for waiting for the process finish.

    It doesn't require subscription on POSIX signal
    but a thread creation is not free.

    The watcher has O(1) complexity, its performance doesn't depend
    on amount of spawn processes.
    c                 C   s   t d| _i | _d S r   )	itertoolsr   _pid_counter_threadsr   r   r   r   r     s    zThreadedChildWatcher.__init__c                 C   s   dS r  r   r   r   r   r   rc     s    zThreadedChildWatcher.is_activec                 C   s   d S r   r   r   r   r   r   r&     s    zThreadedChildWatcher.closec                 C   s   | S r   r   r   r   r   r   r>    s    zThreadedChildWatcher.__enter__c                 C   s   d S r   r   rg  r   r   r   rC    s    zThreadedChildWatcher.__exit__c                 C   s6   dd t | j D }|r2|| j dt| d d S )Nc                 S   s   g | ]}|  r|qS r   )is_alive).0threadr   r   r   
<listcomp>  s    z0ThreadedChildWatcher.__del__.<locals>.<listcomp>z0 has registered but not finished child processesr$   )r)   rq  valuesr#   r-   )r    r  threadsr   r   r   r    s    zThreadedChildWatcher.__del__c                 G   sF   t  }tj| jdt| j ||||fdd}|| j|< |  d S )Nzwaitpid-T)targetnamerJ   daemon)	r   rk  r`  ThreadrN  nextrp  rq  start)r    rx   rI   rJ   r   rt  r   r   r   rf     s    

z&ThreadedChildWatcher.add_child_handlerc                 C   s   dS r  r   r:  r   r   r   r;    s    z)ThreadedChildWatcher.remove_child_handlerc                 C   s   d S r   r   r<  r   r   r   r=    s    z ThreadedChildWatcher.attach_loopc                 C   s   |dkst zt|d\}}W n( tk
rH   |}d}td| Y n X t|}| rhtd|| |	 rtd|| n|j
|||f|  | j| d S )Nr   rX  rY  rZ  rl  )r   r   r\  r^  r   r#  rI  r   r   rm  rv   rq  r_  )r    r   rM  rI   rJ   rx   rH  ry   r   r   r   rN    s(    
 z ThreadedChildWatcher._do_waitpidN)r   r   r   r   r   rc   r&   r>  rC  r+   r,   r  rf   r;  r=  rN  r   r   r   r   r     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   6  s    
z$_UnixDefaultEventLoopPolicy.__init__c              	   C   sH   t j8 | jd kr:t | _tt tjr:| j| j	j
 W 5 Q R X d S r   )r   rb  r  r   rV   r`  current_thread_MainThreadr=  _localr   r   r   r   r   _init_watcher:  s    
z)_UnixDefaultEventLoopPolicy._init_watcherc                    s6   t  | | jdk	r2tt tjr2| j| dS )zSet 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  rV   r`  r  r  r=  r<  r"   r   r   r  B  s
    
z*_UnixDefaultEventLoopPolicy.set_event_loopc                 C   s   | j dkr|   | j S )z~Get the watcher for child processes.

        If not yet set, a ThreadedChildWatcher object is automatically created.
        N)r  r  r   r   r   r   rb   P  s    
z-_UnixDefaultEventLoopPolicy.get_child_watcherc                 C   s4   |dkst |tst| jdk	r*| j  || _dS )z$Set the watcher for child processes.N)rV   r   r   r  r&   )r    rs   r   r   r   set_child_watcherZ  s    

z-_UnixDefaultEventLoopPolicy.set_child_watcher)r   r   r   r   r   _loop_factoryr   r  r  rb   r  r   r   r   r"   r   r~  2  s   
r~  )2r   rG   r   ro  r   r   r=   r   r   r0  r'   r`  r+    r   r   r   r   r   r   r	   r
   r   r   logr   __all__r  ImportErrorr   ZBaseSelectorEventLoopr   ReadTransportrY   _FlowControlMixinWriteTransportr`   ZBaseSubprocessTransportre   r   rI  rJ  r   r   r   r   BaseDefaultEventLoopPolicyr~  r   r   r   r   r   r   <module>   s`   	
    	 NO5JiyR3