grthtrhthjhtyjytjytkergtrhtrjytjerhrfh3 \”‘ã @s dZddlZddlZddlZddlZddlZddlZddlZddlZddl Z ddl m Z ddl m Z ddl m Z ddl mZddl mZdd l mZdd l mZdd l mZdd l mZdd l mZddlmZddlmZdddddgZejdkrüedƒ‚dd„Zy ejZWnek �r,dd„ZYnXGdd„dejƒZ e!edƒ�rVdd„Z"nddl#Z#d d„Z"Gd!d"„d"ej$ƒZ%Gd#d$„d$ej&ej'ƒZ(e!ed%ƒ�r¢ej)Z*nddl#Z#d&d'„Z*Gd(d)„d)e j+ƒZ,Gd*d„dƒZ-Gd+d,„d,e-ƒZ.Gd-d„de.ƒZ/Gd.d„de.ƒZ0Gd/d0„d0ej1ƒZ2e Z3e2Z4dS)1z2Selector event loop for Unix with signal handling.éNé)Ú base_events)Úbase_subprocess)Úcompat)Ú constants)Ú coroutines)Úevents)Úfutures)Úselector_events)Ú selectors)Ú transports)Ú coroutine)ÚloggerÚSelectorEventLoopÚAbstractChildWatcherÚSafeChildWatcherÚFastChildWatcherÚDefaultEventLoopPolicyZwin32z+Signals are not really supported on WindowscCsdS)zDummy signal handler.N©)ÚsignumÚframerrú+/usr/lib64/python3.6/asyncio/unix_events.pyÚ_sighandler_noop%srcCs|S)Nr)ÚpathrrrÚ.srcs¶eZdZdZd"‡fdd„ Zdd„Z‡fdd„Zd d „Zd d „Zd d„Z dd„Z dd„Z d#dd„Z d$dd„Z ed%dd„ƒZdd„Zeddddœdd„ƒZed&ddddœd d!„ƒZ‡ZS)'Ú_UnixSelectorEventLoopzdUnix event loop. Adds signal handling and UNIX Domain Socket support to SelectorEventLoop. Ncstƒj|ƒi|_dS)N)ÚsuperÚ__init__Ú_signal_handlers)ÚselfÚselector)Ú __class__rrr7s z_UnixSelectorEventLoop.__init__cCstjƒS)N)ÚsocketZ socketpair)rrrrÚ _socketpair;sz"_UnixSelectorEventLoop._socketpaircs^tƒjƒtjƒs2xFt|jƒD]}|j|ƒqWn(|jrZtjd|›d�t |d�|jj ƒdS)NzClosing 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!rrr%>s z_UnixSelectorEventLoop.closecCs"x|D]}|sq|j|ƒqWdS)N)Ú_handle_signal)rÚdatarrrrÚ_process_self_dataLs z)_UnixSelectorEventLoop._process_self_datac+GsHtj|ƒstj|ƒrtdƒ‚|j|ƒ|jƒytj|jj ƒƒWn2t t fk rt}zt t |ƒƒ‚WYdd}~XnXtj|||ƒ}||j|<ytj|tƒtj|dƒWn˜t k �rB}zz|j|=|j�sytjdƒWn4t t fk �r}ztjd|ƒWYdd}~XnX|jtjk�r0t dj|ƒƒ‚n‚WYdd}~XnXdS)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()NFrzset_wakeup_fd(-1) failed: %szsig {} cannot be caughtéÿÿÿÿ)rZ iscoroutineZiscoroutinefunctionÚ TypeErrorÚ _check_signalZ _check_closedÚsignalÚ set_wakeup_fdZ_csockÚfilenoÚ ValueErrorÚOSErrorÚ RuntimeErrorÚstrrZHandlerrÚ siginterruptrÚinfoÚerrnoÚEINVALÚformat)rr.ÚcallbackÚargsÚexcÚhandleZnexcrrrÚadd_signal_handlerSs0     z)_UnixSelectorEventLoop.add_signal_handlercCs8|jj|ƒ}|dkrdS|jr*|j|ƒn |j|ƒdS)z2Internal helper that is the actual signal handler.N)rÚgetZ _cancelledr)Z_add_callback_signalsafe)rr.rDrrrr/€s   z%_UnixSelectorEventLoop._handle_signalc&Csâ|j|ƒy |j|=Wntk r*dSX|tjkr>tj}ntj}ytj||ƒWn@tk r”}z$|jtj kr‚t dj |ƒƒ‚n‚WYdd}~XnX|jsÞytj dƒWn2t tfk rÜ}ztjd|ƒWYdd}~XnXdS)zwRemove a handler for a signal. UNIX only. Return True if a signal handler was removed, False if not. Fzsig {} cannot be caughtNrzset_wakeup_fd(-1) failed: %sTr2)r4rÚKeyErrorr5ÚSIGINTÚdefault_int_handlerÚSIG_DFLr9r>r?r:r@r6r8rr=)rr.ZhandlerrCrrrr)Šs(    z,_UnixSelectorEventLoop.remove_signal_handlercCsHt|tƒstdj|ƒƒ‚d|ko,tjknsDtdj|tjƒƒ‚dS)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. zsig must be an int, not {!r}rzsig {} out of range(1, {})N)Ú isinstanceÚintr3r@r5ÚNSIGr8)rr.rrrr4ªs  z$_UnixSelectorEventLoop._check_signalcCst|||||ƒS)N)Ú_UnixReadPipeTransport)rÚpipeÚprotocolÚwaiterÚextrarrrÚ_make_read_pipe_transport·sz0_UnixSelectorEventLoop._make_read_pipe_transportcCst|||||ƒS)N)Ú_UnixWritePipeTransport)rrOrPrQrRrrrÚ_make_write_pipe_transport»sz1_UnixSelectorEventLoop._make_write_pipe_transportc ks´tjƒ�¢} |jƒ} t||||||||f| |dœ| —Ž} | j| jƒ|j| ƒy| EdHWn&tk r~} z | }WYdd} ~ XnXd}|dk r¦| jƒ| j ƒEdH|‚WdQRX| S)N)rQrR) rÚget_child_watcherZ create_futureÚ_UnixSubprocessTransportÚadd_child_handlerZget_pidÚ_child_watcher_callbackÚ Exceptionr%Z_wait)rrPrBÚshellÚstdinÚstdoutÚstderrÚbufsizerRÚkwargsÚwatcherrQÚtransprCÚerrrrrÚ_make_subprocess_transport¿s$     z1_UnixSelectorEventLoop._make_subprocess_transportcCs|j|j|ƒdS)N)Zcall_soon_threadsafeZ_process_exited)rÚpidÚ returncoderbrrrrYÝsz._UnixSelectorEventLoop._child_watcher_callback)ÚsslÚsockÚserver_hostnamec csî|r|dkr&tdƒ‚n|dk r&tdƒ‚|dk rŠ|dk r>tdƒ‚tjtjtjdƒ}y |jdƒ|j||ƒEdHWqÌ|jƒ‚YqÌXnB|dkrštdƒ‚|jtjks´tj |j ƒ rÂtdj |ƒƒ‚|jdƒ|j ||||ƒEdH\}}||fS)Nz/you have to pass server_hostname when using sslz+server_hostname is only meaningful with sslz3path and sock can not be specified at the same timerFzno path and sock were specifiedz2A UNIX Domain Stream Socket was expected, got {!r}) r8r"ÚAF_UNIXÚ SOCK_STREAMÚ setblockingZ sock_connectr%ÚfamilyrÚ_is_stream_socketÚtyper@Z_create_connection_transport)rÚprotocol_factoryrrgrhriÚ transportrPrrrÚcreate_unix_connectionàs8    z-_UnixSelectorEventLoop.create_unix_connectionéd)rhÚbacklogrgc !Cs¤t|tƒrtdƒ‚|dk �r0|dk r,tdƒ‚t|ƒ}tjtjtjƒ}|dd kr´y tj t j|ƒj ƒrnt j |ƒWnBt k r„Yn0tk r²}ztjd||ƒWYdd}~XnXy|j|ƒWnjtk �r}z8|jƒ|jtjk�rdj|ƒ}ttj|ƒd‚n‚WYdd}~Xn|jƒ‚YnXn>|dk�rBtdƒ‚|jtjk�s`tj|jƒ �rntdj|ƒƒ‚tj||gƒ} |j|ƒ|jd ƒ|j|||| ƒ| S) Nz*ssl argument must be an SSLContext or Nonez3path and sock can not be specified at the same timerúz2Unable to check or remove stale UNIX socket %r: %rzAddress {!r} is already in usez-path was not specified, and no sock specifiedz2A UNIX Domain Stream Socket was expected, got {!r}F)rru)rKÚboolr3r8Ú_fspathr"rjrkÚstatÚS_ISSOCKÚosÚst_modeÚremoveÚFileNotFoundErrorr9rÚerrorZbindr%r>Z EADDRINUSEr@rmrrnroZServerZlistenrlZ_start_serving) rrprrhrtrgrcrCÚmsgZserverrrrÚcreate_unix_serversP         z)_UnixSelectorEventLoop.create_unix_server)N)NN)NN)N)N)Ú__name__Ú __module__Ú __qualname__Ú__doc__rr#r%r1rEr/r)r4rSrUr rdrYrrr€Ú __classcell__rr)r!rr1s, -      %rÚ set_blockingcCstj|dƒdS)NF)rzr†)ÚfdrrrÚ_set_nonblockingBsrˆcCs,tj|tjƒ}|tjB}tj|tj|ƒdS)N)ÚfcntlZF_GETFLrzÚ O_NONBLOCKZF_SETFL)r‡ÚflagsrrrrˆGs csŠeZdZdZd ‡fdd„ Zdd„Zdd „Zd d „Zd d „Zdd„Z dd„Z dd„Z dd„Z e jrhdd„Zd!dd„Zdd„Zdd„Z‡ZS)"rNéiNcsÐtƒj|ƒ||jd<||_||_|jƒ|_||_d|_t j |jƒj }t j |ƒpbt j|ƒpbt j|ƒs~d|_d|_d|_tdƒ‚t|jƒ|jj|jj|ƒ|jj|jj|j|jƒ|dk rÌ|jjtj|dƒdS)NrOFz)Pipe transport is for pipes/sockets only.)rrÚ_extraÚ_loopÚ_piper7Ú_filenoÚ _protocolÚ_closingrzÚfstatr{rxÚS_ISFIFOryÚS_ISCHRr8rˆÚ call_soonÚconnection_madeÚ _add_readerÚ _read_readyr Ú_set_result_unless_cancelled)rÚlooprOrPrQrRÚmode)r!rrrQs,          z_UnixReadPipeTransport.__init__cCs¼|jjg}|jdkr |jdƒn|jr0|jdƒ|jd|jƒt|jddƒ}|jdk rŽ|dk rŽtj ||jt j ƒ}|r‚|jdƒq®|jdƒn |jdk r¤|jdƒn |jdƒdd j |ƒS) NÚclosedÚclosingzfd=%sÚ _selectorÚpollingÚidleÚopenz<%s>ú ) r!r�r�Úappendr’r�ÚgetattrrŽr Ú_test_selector_eventr Z EVENT_READÚjoin)rr=r r rrrÚ__repr__ns$          z_UnixReadPipeTransport.__repr__cCsºytj|j|jƒ}WnDttfk r,YnŠtk rX}z|j|dƒWYdd}~Xn^X|rl|jj |ƒnJ|j j ƒr‚t j d|ƒd|_|j j|jƒ|j j|jjƒ|j j|jdƒdS)Nz"Fatal read error on pipe transportz%r was closed by peerT)rzÚreadr�Úmax_sizeÚBlockingIOErrorÚInterruptedErrorr9Ú _fatal_errorr‘Z data_receivedrŽÚ get_debugrr=r’Ú_remove_readerr–Z eof_receivedÚ_call_connection_lost)rr0rCrrrr™„s  z"_UnixReadPipeTransport._read_readycCs|jj|jƒdS)N)rŽr¯r�)rrrrÚ pause_reading–sz$_UnixReadPipeTransport.pause_readingcCs|jj|j|jƒdS)N)rŽr˜r�r™)rrrrÚresume_reading™sz%_UnixReadPipeTransport.resume_readingcCs ||_dS)N)r‘)rrPrrrÚ set_protocolœsz#_UnixReadPipeTransport.set_protocolcCs|jS)N)r‘)rrrrÚ get_protocolŸsz#_UnixReadPipeTransport.get_protocolcCs|jS)N)r’)rrrrÚ is_closing¢sz!_UnixReadPipeTransport.is_closingcCs|js|jdƒdS)N)r’Ú_close)rrrrr%¥sz_UnixReadPipeTransport.closecCs,|jdk r(tjd|t|d�|jjƒdS)Nzunclosed transport %r)r$)r�r*r+r,r%)rrrrÚ__del__­s  z_UnixReadPipeTransport.__del__úFatal error on pipe transportcCsZt|tƒr4|jtjkr4|jjƒrLtjd||dd�n|jj||||j dœƒ|j |ƒdS)Nz%r: %sT)Úexc_info)ÚmessageÚ exceptionrqrP) rKr9r>ZEIOrŽr®rÚdebugÚcall_exception_handlerr‘r¶)rrCrºrrrr­³s  z#_UnixReadPipeTransport._fatal_errorcCs(d|_|jj|jƒ|jj|j|ƒdS)NT)r’rŽr¯r�r–r°)rrCrrrr¶Ász_UnixReadPipeTransport._closec Cs4z|jj|ƒWd|jjƒd|_d|_d|_XdS)N)r‘Úconnection_lostr�r%rŽ)rrCrrrr°Æs  z,_UnixReadPipeTransport._call_connection_losti)NN)r¸)r�r‚rƒrªrr¨r™r±r²r³r´rµr%rÚPY34r·r­r¶r°r…rr)r!rrNMs rNcs¨eZdZd%‡fdd„ Zdd„Zdd„Zdd „Zd d „Zd d „Zdd„Z dd„Z dd„Z dd„Z dd„Z dd„Zejr|dd„Zdd„Zd&dd „Zd'd!d"„Zd#d$„Z‡ZS)(rTNc sütƒj||ƒ||jd<||_|jƒ|_||_tƒ|_d|_ d|_ t j |jƒj }tj|ƒ}tj|ƒ}tj|ƒ} |px|px| s”d|_d|_d|_tdƒ‚t|jƒ|jj|jj|ƒ| sÆ|rÞtjjdƒ rÞ|jj|jj|j|jƒ|dk rø|jjtj|dƒdS)NrOrFz?Pipe transport is only for pipes, sockets and character devicesÚaix)rrr�r�r7r�r‘Ú bytearrayÚ_bufferÚ _conn_lostr’rzr“r{rxr•r”ryr8rˆrŽr–r—r&ÚplatformÚ startswithr˜r™r rš) rr›rOrPrQrRrœZis_charZis_fifoZ is_socket)r!rrrÓs2          z _UnixWritePipeTransport.__init__cCsÒ|jjg}|jdkr |jdƒn|jr0|jdƒ|jd|jƒt|jddƒ}|jdk r¤|dk r¤tj ||jt j ƒ}|r‚|jdƒn |jdƒ|j ƒ}|jd|ƒn |jdk rº|jdƒn |jdƒd d j |ƒS) Nr�ržzfd=%srŸr r¡z bufsize=%sr¢z<%s>r£)r!r�r�r¤r’r�r¥rŽr r¦r Z EVENT_WRITEÚget_write_buffer_sizer§)rr=r r r_rrrr¨øs(          z _UnixWritePipeTransport.__repr__cCs t|jƒS)N)ÚlenrÂ)rrrrrÆsz-_UnixWritePipeTransport.get_write_buffer_sizecCs6|jjƒrtjd|ƒ|jr*|jtƒƒn|jƒdS)Nz%r was closed by peer)rŽr®rr=rÂr¶ÚBrokenPipeError)rrrrr™s   z#_UnixWritePipeTransport._read_readycCst|tƒrt|ƒ}|sdS|js&|jrN|jtjkrs&   z$_UnixWritePipeTransport._write_readycCsdS)NTr)rrrrÚ can_write_eofXsz%_UnixWritePipeTransport.can_write_eofcCs8|jr dSd|_|js4|jj|jƒ|jj|jdƒdS)NT)r’rÂrŽr¯r�r–r°)rrrrÚ write_eof[s z!_UnixWritePipeTransport.write_eofcCs ||_dS)N)r‘)rrPrrrr³dsz$_UnixWritePipeTransport.set_protocolcCs|jS)N)r‘)rrrrr´gsz$_UnixWritePipeTransport.get_protocolcCs|jS)N)r’)rrrrrµjsz"_UnixWritePipeTransport.is_closingcCs|jdk r|j r|jƒdS)N)r�r’rÐ)rrrrr%msz_UnixWritePipeTransport.closecCs,|jdk r(tjd|t|d�|jjƒdS)Nzunclosed transport %r)r$)r�r*r+r,r%)rrrrr·vs  z_UnixWritePipeTransport.__del__cCs|jdƒdS)N)r¶)rrrrÚabort|sz_UnixWritePipeTransport.abortúFatal error on pipe transportcCsPt|tjƒr*|jjƒrBtjd||dd�n|jj||||jdœƒ|j |ƒdS)Nz%r: %sT)r¹)rºr»rqrP) rKrZ_FATAL_ERROR_IGNORErŽr®rr¼r½r‘r¶)rrCrºrrrr­s   z$_UnixWritePipeTransport._fatal_errorcCsFd|_|jr|jj|jƒ|jjƒ|jj|jƒ|jj|j|ƒdS)NT) r’rÂrŽrÎr�r-r¯r–r°)rrCrrrr¶�s  z_UnixWritePipeTransport._closec Cs4z|jj|ƒWd|jjƒd|_d|_d|_XdS)N)r‘r¾r�r%rŽ)rrCrrrr°•s  z-_UnixWritePipeTransport._call_connection_lost)NN)rÒ)N)r�r‚rƒrr¨rÆr™rËrÌrÏrÐr³r´rµr%rr¿r·rÑr­r¶r°r…rr)r!rrTÐs$% !   rTÚset_inheritablecCsNttddƒ}tj|tjƒ}|s4tj|tj||Bƒntj|tj||@ƒdS)NZ FD_CLOEXECr)r¥r‰ZF_GETFDZF_SETFD)r‡Z inheritableZ cloexec_flagÚoldrrrÚ_set_inheritable¥s  rÕc@seZdZdd„ZdS)rWc Ksvd}|tjkr*|jjƒ\}}t|jƒdƒtj|f||||d|dœ|—Ž|_|dk rr|jƒt |j ƒd|d�|j_ dS)NF)r[r\r]r^Zuniversal_newlinesr_Úwb)Ú buffering) Ú subprocessÚPIPErŽr#rÕr7ÚPopenÚ_procr%r¢Údetachr\) rrBr[r\r]r^r_r`Zstdin_wrrrÚ_start±s  z_UnixSubprocessTransport._startN)r�r‚rƒrÝrrrrrW¯srWc@s@eZdZdZdd„Zdd„Zdd„Zdd „Zd d „Zd d „Z dS)raHAbstract 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. cGs tƒ‚dS)aRegister 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)rrerArBrrrrXßs z&AbstractChildWatcher.add_child_handlercCs tƒ‚dS)z Removes the handler for process 'pid'. The function returns True if the handler was successfully removed, False if there was nothing to remove.N)rÞ)rrerrrÚremove_child_handlerêsz)AbstractChildWatcher.remove_child_handlercCs tƒ‚dS)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. N)rÞ)rr›rrrÚ attach_loopòsz AbstractChildWatcher.attach_loopcCs tƒ‚dS)zlClose the watcher. This must be called to make sure that any underlying resource is freed. N)rÞ)rrrrr%üszAbstractChildWatcher.closecCs tƒ‚dS)zdEnter the watcher's context and allow starting new processes This function must return selfN)rÞ)rrrrÚ __enter__szAbstractChildWatcher.__enter__cCs tƒ‚dS)zExit the watcher's contextN)rÞ)rÚaÚbÚcrrrÚ__exit__ szAbstractChildWatcher.__exit__N) r�r‚rƒr„rXrßràr%rárårrrrrÈs  c@sDeZdZdd„Zdd„Zdd„Zdd„Zd d „Zd d „Zd d„Z dS)ÚBaseChildWatchercCsd|_i|_dS)N)rŽÚ _callbacks)rrrrrszBaseChildWatcher.__init__cCs|jdƒdS)N)rà)rrrrr%szBaseChildWatcher.closecCs tƒ‚dS)N)rÞ)rÚ expected_pidrrrÚ _do_waitpidszBaseChildWatcher._do_waitpidcCs tƒ‚dS)N)rÞ)rrrrÚ_do_waitpid_allsz BaseChildWatcher._do_waitpid_allcCsf|jdk r$|dkr$|jr$tjdtƒ|jdk r<|jjtjƒ||_|dk rb|jtj|j ƒ|j ƒdS)NzCA loop is being detached from a child watcher with pending handlers) rŽrçr*r+ÚRuntimeWarningr)r5ÚSIGCHLDrEÚ _sig_chldrê)rr›rrrràs zBaseChildWatcher.attach_loopcCsFy |jƒWn4tk r@}z|jjd|dœƒWYdd}~XnXdS)Nz$Unknown exception in SIGCHLD handler)rºr»)rêrZrŽr½)rrCrrrrí1s  zBaseChildWatcher._sig_chldcCs2tj|ƒrtj|ƒ Stj|ƒr*tj|ƒS|SdS)N)rzÚ WIFSIGNALEDÚWTERMSIGÚ WIFEXITEDÚ WEXITSTATUS)rÚstatusrrrÚ_compute_returncode=s     z$BaseChildWatcher._compute_returncodeN) r�r‚rƒrr%rérêràrírórrrrræs ræcsPeZdZdZ‡fdd„Zdd„Zdd„Zdd „Zd d „Zd d „Z dd„Z ‡Z S)rad'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) cs|jjƒtƒjƒdS)N)rçr-rr%)r)r!rrr%Vs zSafeChildWatcher.closecCs|S)Nr)rrrrráZszSafeChildWatcher.__enter__cCsdS)Nr)rrârãrärrrrå]szSafeChildWatcher.__exit__cGs.|jdkrtdƒ‚||f|j|<|j|ƒdS)NzICannot add child handler, the child watcher does not have a loop attached)rŽr:rçré)rrerArBrrrrX`s  z"SafeChildWatcher.add_child_handlerc Cs&y |j|=dStk r dSXdS)NTF)rçrG)rrerrrrßks z%SafeChildWatcher.remove_child_handlercCs"xt|jƒD]}|j|ƒq WdS)N)r(rçré)rrerrrrêrsz SafeChildWatcher._do_waitpid_allcCsÆytj|tjƒ\}}Wn(tk r>|}d}tjd|ƒYn0X|dkrLdS|j|ƒ}|jjƒrntj d||ƒy|j j |ƒ\}}Wn.t k r°|jjƒr¬tjd|dd�YnX|||f|žŽdS)Néÿz8Unknown child process pid %d, will report returncode 255rz$process %s exited with returncode %sz'Child watcher got an unexpected pid: %rT)r¹) rzÚwaitpidÚWNOHANGÚChildProcessErrorrrÊrórŽr®r¼rçÚpoprG)rrèreròrfrArBrrrréws*    zSafeChildWatcher._do_waitpid) r�r‚rƒr„r%rárårXrßrêrér…rr)r!rrKs   csTeZdZdZ‡fdd„Z‡fdd„Zdd„Zdd „Zd d „Zd d „Z dd„Z ‡Z S)raW'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). cs$tƒjƒtjƒ|_i|_d|_dS)Nr)rrÚ threadingZLockÚ_lockÚ_zombiesÚ_forks)r)r!rrr¤s  zFastChildWatcher.__init__cs"|jjƒ|jjƒtƒjƒdS)N)rçr-rûrr%)r)r!rrr%ªs  zFastChildWatcher.closec Cs$|j�|jd7_|SQRXdS)Nr)rúrü)rrrrrá¯szFastChildWatcher.__enter__c CsV|j�:|jd8_|js$|j r(dSt|jƒ}|jjƒWdQRXtjd|ƒdS)Nrz5Caught subprocesses termination from unknown pids: %s)rúrürûr;r-rrÊ)rrârãräZcollateral_victimsrrrråµs zFastChildWatcher.__exit__cGsl|jdkrtdƒ‚|j�:y|jj|ƒ}Wn"tk rL||f|j|<dSXWdQRX|||f|žŽdS)NzICannot add child handler, the child watcher does not have a loop attached)rŽr:rúrûrørGrç)rrerArBrfrrrrXÃs z"FastChildWatcher.add_child_handlerc Cs&y |j|=dStk r dSXdS)NTF)rçrG)rrerrrrßÖs z%FastChildWatcher.remove_child_handlercCsöxðytjdtjƒ\}}Wntk r,dSX|dkr:dS|j|ƒ}|j�vy|jj|ƒ\}}WnBtk r¢|j rš||j |<|j j ƒr˜t jd||ƒwd}YnX|j j ƒr¼t jd||ƒWdQRX|dkrÞt jd||ƒq|||f|žŽqWdS)Nrrz,unknown process %s exited with returncode %sz$process %s exited with returncode %sz8Caught subprocess termination from unknown pid: %d -> %dr2)rzrõrör÷rórúrçrørGrürûrŽr®rr¼rÊ)rreròrfrArBrrrrêÝs6      z FastChildWatcher._do_waitpid_all) r�r‚rƒr„rr%rárårXrßrêr…rr)r!rršs   csHeZdZdZeZ‡fdd„Zdd„Z‡fdd„Zdd „Z d d „Z ‡Z S) Ú_UnixDefaultEventLoopPolicyz:UNIX event loop policy with a watcher for child processes.cstƒjƒd|_dS)N)rrÚ_watcher)r)r!rrr s z$_UnixDefaultEventLoopPolicy.__init__c CsHtj�8|jdkr:tƒ|_ttjƒtjƒr:|jj|j j ƒWdQRXdS)N) rrúrþrrKrùÚcurrent_threadÚ _MainThreadràÚ_localrŽ)rrrrÚ _init_watchers  z)_UnixDefaultEventLoopPolicy._init_watchercs6tƒj|ƒ|jdk r2ttjƒtjƒr2|jj|ƒdS)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þrKrùrÿrrà)rr›)r!rrrs  z*_UnixDefaultEventLoopPolicy.set_event_loopcCs|jdkr|jƒ|jS)zzGet the watcher for child processes. If not yet set, a SafeChildWatcher object is automatically created. N)rþr)rrrrrV&s z-_UnixDefaultEventLoopPolicy.get_child_watchercCs|jdk r|jjƒ||_dS)z$Set the watcher for child processes.N)rþr%)rrarrrÚset_child_watcher0s  z-_UnixDefaultEventLoopPolicy.set_child_watcher) r�r‚rƒr„rZ _loop_factoryrrrrVrr…rr)r!rrýs   rý)5r„r>rzr5r"rxrØr&rùr*Úrrrrrrr r r r r ÚlogrÚ__all__rÄÚ ImportErrorrÚfspathrwÚAttributeErrorZBaseSelectorEventLooprÚhasattrrˆr‰Z ReadTransportrNZ_FlowControlMixinZWriteTransportrTrÓrÕZBaseSubprocessTransportrWrrærrZBaseDefaultEventLoopPolicyrýrrrrrrÚsn                O  F=On2