£Á°èZ¨Ä…–K§‚«“ô4“ÒÙ´dîfUÙÃÅ WKbyÊ¦•êŽ…È®FÒ¿ÊÎóCozá¬S@6{Í:›œêZÌ:Š•_%:¢¾¾~;‘Ã~èŠ©ÊÇí`ÔÑ©úë™µ'5I¿fš×WO%ø9¾«¾DK|€ùÍD”Ýs]nHÕ¶ê×Ó¼ãžªéUWŸÈË%DÒÕ¬ï‘]/Åcx  ‰ï2ß]ä6G[]S£ÔÏ¯rs{úëóµmÒï#UQxo·õÞCe]"±/aÙ&Eã4ú9Jé_ÞåëdãöKë)AÞ                  ¯¹ægƒÛowÐø^d™ý½ßB7áyMä9ÜÖUã
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
<html>
B
     f؟                 @   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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%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*Z,dS )%z2Selector event loop for Unix with signal handling.    N   )base_events)base_subprocess)	constants)
coroutines)events)futures)selector_events)tasks)
transports)logger)SelectorEventLoopAbstractChildWatcherSafeChildWatcherFastChildWatcherDefaultEventLoopPolicyZwin32z+Signals are not really supported on Windowsc             C   s   dS )zDummy signal handler.N )signumframer   r   8/opt/alt/python37/lib64/python3.7/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   2   s    z_UnixSelectorEventLoop.__init__c                s^   t    t s2xFt| jD ]}| | qW n(| jrZt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   sig)r   r   r   r   6   s    
z_UnixSelectorEventLoop.closec             C   s"   x|D ]}|sq|  | qW d S )N)_handle_signal)r   datar   r   r   r   _process_self_dataD   s    
z)_UnixSelectorEventLoop._process_self_datac             G   sL  t |st |rtd| | |   yt| j	  W n2 t
tfk
rt } ztt|W dd}~X Y nX t||| d}|| j|< yt|t t|d W n tk
rF } zz| j|= | jsytd W n4 t
tfk
r } ztd| W dd}~X Y nX |jtjkr4td| dn W d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()NFzset_wakeup_fd(-1) failed: %szsig z cannot be caught)r   ZiscoroutineZiscoroutinefunction	TypeError_check_signalZ_check_closedsignalset_wakeup_fdZ_csockfileno
ValueErrorOSErrorRuntimeErrorstrr   ZHandler   r   siginterruptr   infoerrnoEINVAL)r   r(   callbackargsexchandleZnexcr   r   r   add_signal_handlerK   s0    



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   getZ
_cancelledr#   Z_add_callback_signalsafe)r   r(   r=   r   r   r   r)   x   s    z%_UnixSelectorEventLoop._handle_signalc          
   C   s   |  | y| j|= W n tk
r*   dS X |tjkr>tj}ntj}yt|| W nB tk
r } z$|jtj	krt
d| dn W dd}~X Y nX | jsytd W n2 ttfk
r } ztd| W d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.
        Fzsig z cannot be caughtNr,   zset_wakeup_fd(-1) failed: %sT)r.   r   KeyErrorr/   SIGINTdefault_int_handlerSIG_DFLr3   r8   r9   r4   r0   r2   r   r7   )r   r(   Zhandlerr<   r   r   r   r#      s(    

z,_UnixSelectorEventLoop.remove_signal_handlerc             C   sL   t |tstd|d|  kr.tjk sHn td| dtj 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 r   zsig z out of range(1, )N)
isinstanceintr-   r/   NSIGr2   )r   r(   r   r   r   r.      s    
z$_UnixSelectorEventLoop._check_signalc             C   s   t | ||||S )N)_UnixReadPipeTransport)r   pipeprotocolwaiterextrar   r   r   _make_read_pipe_transport   s    z0_UnixSelectorEventLoop._make_read_pipe_transportc             C   s   t | ||||S )N)_UnixWritePipeTransport)r   rI   rJ   rK   rL   r   r   r   _make_write_pipe_transport   s    z1_UnixSelectorEventLoop._make_write_pipe_transportc	          
      s   t  }
|  }t| |||||||f||d|	}|
| | j| y|I d H  W n, tk
r   |  |	 I d H   Y nX W d Q R X |S )N)rK   rL   )
r   get_child_watchercreate_future_UnixSubprocessTransportadd_child_handlerZget_pid_child_watcher_callback	Exceptionr   Z_wait)r   rJ   r;   shellstdinstdoutstderrbufsizerL   kwargswatcherrK   transpr   r   r   _make_subprocess_transport   s    




z1_UnixSelectorEventLoop._make_subprocess_transportc             C   s   |  |j| d S )N)Zcall_soon_threadsafeZ_process_exited)r   pid
returncoder]   r   r   r   rT      s    z._UnixSelectorEventLoop._child_watcher_callback)sslsockserver_hostnamessl_handshake_timeoutc      	         s
  |r|d kr6t dn |d k	r&t d|d k	r6t d|d k	r|d k	rNt dt|}ttjtjd}y |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 sslz1ssl_handshake_timeout is only meaningful with sslz3path and sock can not be specified at the same timer   Fzno path and sock were specifiedz.A UNIX Domain Stream Socket was expected, got )rd   )r2   osfspathsocketAF_UNIXSOCK_STREAMsetblockingZsock_connectr   familytypeZ_create_connection_transport)	r   protocol_factorypathra   rb   rc   rd   	transportrJ   r   r   r   create_unix_connection   s@    



z-_UnixSelectorEventLoop.create_unix_connectiond   T)rb   backlogra   rd   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ry t	
t	|jrt| W nB tk
r   Y n0 tk
r } ztd|| W d d }~X Y nX y|| W nl tk
r0 }	 z8|  |	jtjkrd|d}
ttj|
d n W d 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 Nonez1ssl_handshake_timeout is only meaningful with sslz3path and sock can not be specified at the same timer   )r    z2Unable to check or remove stale UNIX socket %r: %rzAddress z is already in usez-path was not specified, and no sock specifiedz.A UNIX Domain Stream Socket was expected, got F)loop)rE   boolr-   r2   re   rf   rg   rh   ri   statS_ISSOCKst_moderemoveFileNotFoundErrorr3   r   errorZbindr   r8   Z
EADDRINUSErk   rl   rj   r   ZServerZ_start_servingr
   Zsleep)r   rm   rn   rb   rr   ra   rd   rs   errr<   msgZserverr   r   r   create_unix_server   sZ    






z)_UnixSelectorEventLoop.create_unix_serverc          
      s   y
t j W n, tk
r6 } ztdW d d }~X Y nX y| }W n2 ttjfk
rv } ztdW d d }~X Y nX yt |j	}W n, t
k
r } ztdW d 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   )re   sendfileAttributeErrorr   SendfileNotAvailableErrorr1   ioUnsupportedOperationfstatst_sizer3   rQ   _sock_sendfile_native_impl)r   rb   fileoffsetcountr<   r1   r}   Zfsize	blocksizefutr   r   r   _sock_sendfile_native>  s(    
z,_UnixSelectorEventLoop._sock_sendfile_nativec	             C   s  |  }	|d k	r| | | r4| ||| d S |rd|| }|dkrd| ||| || d S yt|	|||}
W n* ttfk
r   |d kr| 	|| | 
|	| j||	||||||
 Y nH 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 d d }~X Y n tk
r } z| ||| || W d 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)r1   remove_writer	cancelled_sock_sendfile_update_fileposZ
set_resultre   r   BlockingIOErrorInterruptedError_sock_add_cancellation_callbackZ
add_writerr   r3   r8   ZENOTCONNrl   ConnectionError	__cause__r   r   Zset_exceptionrU   )r   r   Zregistered_fdrb   r1   r   r   r   
total_sentfdZsentr<   new_excr}   r   r   r   r   U  s`    






z1_UnixSelectorEventLoop._sock_sendfile_native_implc             C   s   |dkrt ||t j d S )Nr   )re   lseekSEEK_SET)r   r1   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 )Nr,   )r   r1   r   )r   r   )r   rb   r   r   cb  s    zB_UnixSelectorEventLoop._sock_add_cancellation_callback.<locals>.cb)Zadd_done_callback)r   r   rb   r   r   )r   rb   r   r     s    z6_UnixSelectorEventLoop._sock_add_cancellation_callback)N)NN)NN)N)N)N)__name__
__module____qualname____doc__r   r   r+   r>   r)   r#   r.   rM   rO   r^   rT   rp   r   r   r   r   r   __classcell__r   r   )r   r   r   ,   s4   -
  
 

*?D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dd ZdddZdd Zdd Z  ZS ) rH   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 )NrI   Fz)Pipe transport is for pipes/sockets only.)r   r   _extra_loop_piper1   _fileno	_protocol_closing_pausedre   r   ry   rw   S_ISFIFOrx   S_ISCHRr2   set_blocking	call_soonconnection_made_add_reader_read_readyr   _set_result_unless_cancelled)r   ru   rI   rJ   rK   rL   mode)r   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closingzfd=	_selectorpollingidleopenz<{}> )r   r   r   appendr   r   getattrr   r	   _test_selector_event	selectorsZ
EVENT_READformatjoin)r   r7   r   r   r   r   r   __repr__  s"    




z_UnixReadPipeTransport.__repr__c          
   C   s   yt | j| j}W nD ttfk
r,   Y n tk
rX } z| |d W d 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 transportz%r was closed by peerT)re   readr   max_sizer   r   r3   _fatal_errorr   Zdata_receivedr   	get_debugr   r7   r   _remove_readerr   Zeof_received_call_connection_lost)r   r*   r<   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 )N)r   )r   rJ   r   r   r   set_protocol  s    z#_UnixReadPipeTransport.set_protocolc             C   s   | j S )N)r   )r   r   r   r   get_protocol  s    z#_UnixReadPipeTransport.get_protocolc             C   s   | j S )N)r   )r   r   r   r   
is_closing  s    z!_UnixReadPipeTransport.is_closingc             C   s   | j s| d  d S )N)r   _close)r   r   r   r   r     s    z_UnixReadPipeTransport.closec             C   s.   | j d k	r*tjd| t| d | j   d S )Nzunclosed transport )r   )r   r$   r%   r&   r   )r   r   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	exceptionro   rJ   )rE   r3   r8   ZEIOr   r   r   r   call_exception_handlerr   r   )r   r<   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   r<   r   r   r   r      s    z_UnixReadPipeTransport._closec             C   s4   z| j | W d | j  d | _d | _ d | _X d S )N)r   connection_lostr   r   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   r   r   r   r   r   r   r   r   r   r   )r   r   rH     s   
rH   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dd Zdd Zd&dd Zd'd!d"Zd#d$ Z  ZS )(rN   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 )NrI   r   Fz?Pipe transport is only for pipes, sockets and character devicesZaix)r   r   r   r   r1   r   r   	bytearray_buffer
_conn_lostr   re   r   ry   rw   r   r   rx   r2   r   r   r   r   r    platform
startswithr   r   r   r   )
r   ru   rI   rJ   rK   rL   r   Zis_charZis_fifoZ	is_socket)r   r   r   r   2  s2    





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   zfd=r   r   r   zbufsize=r   z<{}>r   )r   r   r   r   r   r   r   r   r	   r   r   ZEVENT_WRITEget_write_buffer_sizer   r   )r   r7   r   r   rZ   r   r   r   r   W  s&    





z _UnixWritePipeTransport.__repr__c             C   s
   t | jS )N)lenr   )r   r   r   r   r   o  s    z-_UnixWritePipeTransport.get_write_buffer_sizec             C   s6   | j  rtd|  | jr*| t  n|   d S )Nz%r was closed by peer)r   r   r   r7   r   r   BrokenPipeError)r   r   r   r   r   r  s
    
z#_UnixWritePipeTransport._read_readyc          
   C   s  t |trt|}|sd S | js&| jrN| jtjkr<td |  jd7  _d S | j	syt
| j|}W nV ttfk
r   d}Y n< tk
r } z|  jd7  _| |d d S d }~X Y nX |t|krd S |dkrt||d  }| j| j| j |  j	|7  _	|   d S )Nz=pipe closed by peer or os.write(pipe, data) raised exception.r   r   z#Fatal write error on pipe transport)rE   r   
memoryviewr   r   r   Z!LOG_THRESHOLD_FOR_CONNLOST_WRITESr   warningr   re   writer   r   r   rU   r   r   r   Z_add_writer_write_readyZ_maybe_pause_protocol)r   r*   nr<   r   r   r   r   {  s2    

z_UnixWritePipeTransport.writec          
   C   s   yt | j| j}W nj ttfk
r,   Y n tk
r~ } z6| j  |  jd7  _| j	
| j | |d W d d }~X Y nfX |t| jkr| j  | j	
| j |   | jr| j	| j | d  d S |dkr| jd |= d S )Nr   z#Fatal write error on pipe transportr   )re   r   r   r   r   r   rU   r'   r   r   _remove_writerr   r   Z_maybe_resume_protocolr   r   r   )r   r   r<   r   r   r   r     s&    


z$_UnixWritePipeTransport._write_readyc             C   s   dS )NTr   )r   r   r   r   can_write_eof  s    z%_UnixWritePipeTransport.can_write_eofc             C   s8   | j r
d S d| _ | js4| j| j | j| jd  d S )NT)r   r   r   r   r   r   r   )r   r   r   r   	write_eof  s    z!_UnixWritePipeTransport.write_eofc             C   s
   || _ d S )N)r   )r   rJ   r   r   r   r     s    z$_UnixWritePipeTransport.set_protocolc             C   s   | j S )N)r   )r   r   r   r   r     s    z$_UnixWritePipeTransport.get_protocolc             C   s   | j S )N)r   )r   r   r   r   r     s    z"_UnixWritePipeTransport.is_closingc             C   s   | j d k	r| js|   d S )N)r   r   r   )r   r   r   r   r     s    z_UnixWritePipeTransport.closec             C   s.   | j d k	r*tjd| t| d | j   d S )Nzunclosed transport )r   )r   r$   r%   r&   r   )r   r   r   r   r     s    
z_UnixWritePipeTransport.__del__c             C   s   |  d  d S )N)r   )r   r   r   r   abort  s    z_UnixWritePipeTransport.abortFatal error on pipe transportc             C   sN   t |tr(| j r@tjd| |dd n| j||| | jd | | d S )Nz%r: %sT)r   )r   r   ro   rJ   )	rE   r3   r   r   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 )NT)	r   r   r   r   r   r'   r   r   r   )r   r<   r   r   r   r     s    
z_UnixWritePipeTransport._closec             C   s4   z| j | W d | j  d | _d | _ d | _X d S )N)r   r   r   r   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   rN   /  s"   %	!	

rN   c               @   s   e Zd Zdd ZdS )rR   c       	   	   K   s   d }|t jkrt \}}zPt j|f||||d|d|| _|d k	rh|  t| d|d| j_	d }W d |d k	r|  |  X d S )NF)rV   rW   rX   rY   Zuniversal_newlinesrZ   wb)	buffering)

subprocessPIPErg   Z
socketpairPopen_procr   r   detachrW   )	r   r;   rV   rW   rX   rY   rZ   r[   Zstdin_wr   r   r   _start  s    
z_UnixSubprocessTransport._startN)r   r   r   r   r   r   r   r   rR     s   rR   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   r_   r:   r;   r   r   r   rS   )  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.N)r   )r   r_   r   r   r   remove_child_handler4  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.
        N)r   )r   ru   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.
        N)r   )r   r   r   r   r   F  s    zAbstractChildWatcher.closec             C   s
   t  dS )zdEnter the watcher's context and allow starting new processes

        This function must return selfN)r   )r   r   r   r   	__enter__M  s    zAbstractChildWatcher.__enter__c             C   s
   t  dS )zExit the watcher's contextN)r   )r   abcr   r   r   __exit__S  s    zAbstractChildWatcher.__exit__N)
r   r   r   r   rS   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 | _ i | _d S )N)r   
_callbacks)r   r   r   r   r   Z  s    zBaseChildWatcher.__init__c             C   s   |  d  d S )N)r   )r   r   r   r   r   ^  s    zBaseChildWatcher.closec             C   s
   t  d S )N)r   )r   expected_pidr   r   r   _do_waitpida  s    zBaseChildWatcher._do_waitpidc             C   s
   t  d S )N)r   )r   r   r   r   _do_waitpid_alld  s    z BaseChildWatcher._do_waitpid_allc             C   sf   | j d k	r$|d kr$| jr$tdt | j d k	r<| j tj || _ |d k	rb|tj| j	 | 
  d S )NzCA loop is being detached from a child watcher with pending handlers)r   r   r$   r%   RuntimeWarningr#   r/   SIGCHLDr>   	_sig_chldr   )r   ru   r   r   r   r   g  s    
zBaseChildWatcher.attach_loopc          
   C   sF   y|    W n4 tk
r@ } z| jd|d W d d }~X Y nX d S )Nz$Unknown exception in SIGCHLD handler)r   r   )r   rU   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 )N)re   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   X  s   r   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 )N)r   r'   r   r   )r   )r   r   r   r     s    
zSafeChildWatcher.closec             C   s   | S )Nr   )r   r   r   r   r     s    zSafeChildWatcher.__enter__c             C   s   d S )Nr   )r   r   r   r   r   r   r   r     s    zSafeChildWatcher.__exit__c             G   s.   | j d krtd||f| j|< | | d S )NzICannot add child handler, the child watcher does not have a loop attached)r   r4   r   r   )r   r_   r:   r;   r   r   r   rS     s
    
z"SafeChildWatcher.add_child_handlerc             C   s&   y| j |= dS  tk
r    dS X d S )NTF)r   r@   )r   r_   r   r   r   r     s
    z%SafeChildWatcher.remove_child_handlerc             C   s"   xt | jD ]}| | qW d S )N)r"   r   r   )r   r_   r   r   r   r     s    z SafeChildWatcher._do_waitpid_allc             C   s   yt |t j\}}W n( tk
r>   |}d}td| Y n0X |dkrLd S | |}| j rnt	d|| y| j
|\}}W n. tk
r   | j rtjd|dd Y nX |||f|  d S )N   z8Unknown child process pid %d, will report returncode 255r   z$process %s exited with returncode %sz'Child watcher got an unexpected pid: %rT)r   )re   waitpidWNOHANGChildProcessErrorr   r   r  r   r   r   r   popr@   )r   r   r_   r  r`   r:   r;   r   r   r   r     s*    


zSafeChildWatcher._do_waitpid)r   r   r   r   r   r   r   rS   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    t | _i | _d| _d S )Nr   )r   r   	threadingZLock_lock_zombies_forks)r   )r   r   r   r     s    

zFastChildWatcher.__init__c                s"   | j   | j  t   d S )N)r   r'   r
  r   r   )r   )r   r   r   r     s    

zFastChildWatcher.closec          	   C   s$   | j  |  jd7  _| S Q R X d S )Nr   )r	  r  )r   r   r   r   r     s    zFastChildWatcher.__enter__c          	   C   sT   | j 8 |  jd8  _| js"| js&d S t| j}| j  W d Q R X td| d S )Nr   z5Caught subprocesses termination from unknown pids: %s)r	  r  r
  r5   r'   r   r   )r   r   r   r   Zcollateral_victimsr   r   r   r     s    
zFastChildWatcher.__exit__c          	   G   sl   | j d krtd| j: y| j|}W n" tk
rL   ||f| j|< d S X W d Q R X |||f|  d S )NzICannot add child handler, the child watcher does not have a loop attached)r   r4   r	  r
  r  r@   r   )r   r_   r:   r;   r`   r   r   r   rS     s    
z"FastChildWatcher.add_child_handlerc             C   s&   y| j |= dS  tk
r    dS X d S )NTF)r   r@   )r   r_   r   r   r   r      s
    z%FastChildWatcher.remove_child_handlerc          	   C   s   xyt dt j\}}W n tk
r,   d S X |dkr:d S | |}| jv y| j|\}}W nB tk
r   | j	r|| j
|< | j rtd|| wd }Y nX | j rtd|| W d Q R X |d krtd|| q|||f|  qW d S )Nr,   r   z,unknown process %s exited with returncode %sz$process %s exited with returncode %sz8Caught subprocess termination from unknown pid: %d -> %d)re   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   '  s6    





z FastChildWatcher._do_waitpid_all)r   r   r   r   r   r   r   r   rS   r   r   r   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 )N)r   r   _watcher)r   )r   r   r   r   V  s    
z$_UnixDefaultEventLoopPolicy.__init__c          	   C   sH   t j8 | jd kr:t | _tt tjr:| j| j	j
 W d Q R X d S )N)r   r	  r  r   rE   r  current_thread_MainThreadr   _localr   )r   r   r   r   _init_watcherZ  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  rE   r  r  r  r   )r   ru   )r   r   r   r  b  s    
z*_UnixDefaultEventLoopPolicy.set_event_loopc             C   s   | j dk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   rP   p  s    
z-_UnixDefaultEventLoopPolicy.get_child_watcherc             C   s   | j dk	r| j   || _ dS )z$Set the watcher for child processes.N)r  r   )r   r\   r   r   r   set_child_watcherz  s    

z-_UnixDefaultEventLoopPolicy.set_child_watcher)r   r   r   r   r   Z_loop_factoryr   r  r  rP   r  r   r   r   )r   r   r  R  s   
r  )-r   r8   r   re   r   r/   rg   rw   r   r    r  r$    r   r   r   r   r   r   r	   r
   r   logr   __all__r   ImportErrorr   ZBaseSelectorEventLoopr   ZReadTransportrH   Z_FlowControlMixinZWriteTransportrN   ZBaseSubprocessTransportrR   r   r   r   r   ZBaseDefaultEventLoopPolicyr  r   r   r   r   r   r   <module>   sR   
  | 
 JF=On3