+e؆@sdZddlZddlZddlZddlZddlZddlZddlZddlZddl Z ddl m Z ddl m Z ddl m Z ddl mZddl mZdd l mZdd l mZdd l mZdd l mZdd l mZddlmZddlmZdddddgZejdkreednddZGdddejZeedrddZnddl Z ddZGdd d ej!Z"Gd!d"d"ej#ej$Z%eed#rej&Z'nddl Z d$d%Z'Gd&d'd'e j(Z)Gd(ddZ*Gd)d*d*e*Z+Gd+dde+Z,Gd,dde+Z-Gd-d.d.ej.Z/eZ0e/Z1dS)/z2Selector event loop for Unix with signal handling.N) base_events)base_subprocess)compat) constants) coroutines)events)futures)selector_events) selectors) transports) coroutine)loggerSelectorEventLoopAbstractChildWatcherSafeChildWatcherFastChildWatcherDefaultEventLoopPolicywin32z+Signals are not really supported on WindowscCsdS)zDummy signal handler.N)signumZframerr8/opt/alt/python34/lib64/python3.4/asyncio/unix_events.py_sighandler_noop%src seZdZdZdfddZddZfddZd d Zd d Zd dZ ddZ ddZ ddddZ ddddZ edddZddZeddddddddZedddd d!ddd"d#ZS)$_UnixSelectorEventLoopzdUnix event loop. Adds signal handling and UNIX Domain Socket support to SelectorEventLoop. Ncstj|i|_dS)N)super__init___signal_handlers)selfZselector) __class__rrr0sz_UnixSelectorEventLoop.__init__cCs tjS)N)socketZ socketpair)rrrr _socketpair4sz"_UnixSelectorEventLoop._socketpaircs8tjx$t|jD]}|j|qWdS)N)rcloselistrremove_signal_handler)rsig)rrrr!7s z_UnixSelectorEventLoop.closecCs.x'|D]}|sqn|j|qWdS)N)_handle_signal)rdatarrrr_process_self_data<s z)_UnixSelectorEventLoop._process_self_datac+Gstj|stj|r-tdn|j||jytj|jj Wn=t t fk r}zt t |WYdd}~XnXtj|||}||j| ) rrmr{appendrr|r _test_selector_eventrz _selectorr Z EVENT_READjoin)rr3rrrr__repr__Es   z_UnixReadPipeTransport.__repr__cCsytj|j|j}WnLttfk r6Yntk rj}z|j|dWYdd}~XnX|r|jj |nj|j j rt j d|nd|_|j j|j|j j|jj|j j|jddS)Nz"Fatal read error on pipe transportz%r was closed by peerT)rrreadr|max_sizeBlockingIOErrorInterruptedErrorr/ _fatal_errorrZ data_receivedrz get_debugrr3r remove_readerrZ eof_received_call_connection_lost)rr&r9rrrrXs# z"_UnixReadPipeTransport._read_readycCs|jj|jdS)N)rzrr|)rrrr pause_readingjsz$_UnixReadPipeTransport.pause_readingcCs|jj|j|jdS)N)rzrr|r)rrrrresume_readingmsz%_UnixReadPipeTransport.resume_readingcCs|jS)N)r)rrrr is_closingpsz!_UnixReadPipeTransport.is_closingcCs|js|jdndS)N)r_close)rrrrr!ss z_UnixReadPipeTransport.closecCs7|jdk r3tjd|t|jjndS)Nzunclosed transport %r)r{warningswarnResourceWarningr!)rrrr__del__{sz_UnixReadPipeTransport.__del__zFatal error on pipe transportcCst|trO|jtjkrO|jjr~tjd||ddq~n/|jji|d6|d6|d6|j d6|j |dS)Nz%r: %sexc_infoTmessage exceptionrfrF) rAr/r4ZEIOrzrrdebugcall_exception_handlerrr)rr9rrrrrs! z#_UnixReadPipeTransport._fatal_errorcCs6d|_|jj|j|jj|j|dS)NT)rrzrr|rr)rr9rrrrs z_UnixReadPipeTransport._closec CsDz|jj|Wd|jjd|_d|_d|_XdS)N)rconnection_lostr{r!rz)rr9rrrrs    z,_UnixReadPipeTransport._call_connection_losti)rmrnrorrrrrrrr!rPY34rrrrrr)rrrD*s         rDcseZdZddfddZddZddZdd Zd d Zd d ZddZ ddZ ddZ ddZ e jrddZnddZdddZdddZdd ZS)!rJNcsCtj||||jd<||_|j|_tj|jj}t j |}|p}t j |p}t j |st dnt|j||_g|_d|_d|_|jj|jj||stjjd r|jj|jj|j|jn|dk r?|jjtj|dndS)NrEz?Pipe transport is only for pipes, sockets and character devicesrFaix)rrryr{r-r|rrr}r~rrrrr.rtr_buffer _conn_lostrrzrrsysplatform startswithrrr r)rrLrErFrGrHrZ is_socket)rrrrs,        z _UnixWritePipeTransport.__init__cCs|jjg}|jdkr.|jdn|jrG|jdn|jd|j|jdk rtj|jj |jt j }|r|jdn |jd|j }|jd|n |jdddj |S) Nrrzfd=%srrz bufsize=%sz<%s>r)rrmr{rrr|r rrzrr Z EVENT_WRITEget_write_buffer_sizer)rr3rrVrrrrs"     z _UnixWritePipeTransport.__repr__cCstdd|jDS)Ncss|]}t|VqdS)N)len).0r&rrr sz@_UnixWritePipeTransport.get_write_buffer_size..)sumr)rrrrrsz-_UnixWritePipeTransport.get_write_buffer_sizecCsL|jjr"tjd|n|jr>|jtn |jdS)Nz%r was closed by peer)rzrrr3rrBrokenPipeError)rrrrrs  z#_UnixWritePipeTransport._read_readycCsht|trt|}n|s(dS|js:|jro|jtjkr\tjdn|jd7_dS|j sJyt j |j |}Wnet tfk rd}YnHtk r}z(|jd7_|j|ddSWYdd}~XnX|t|krdS|dkr.||d}n|jj|j |jn|j j||jdS)Nz=pipe closed by peer or os.write(pipe, data) raised exception.rrz#Fatal write error on pipe transport)rA bytearray memoryviewrrrZ!LOG_THRESHOLD_FOR_CONNLOST_WRITESrwarningrrrwriter|rrrQrrrzZ add_writer _write_readyrZ_maybe_pause_protocol)rr&nr9rrrrs2   z_UnixWritePipeTransport.writecCsUdj|j}|jjytj|j|}Wn~ttfk rb|jj|Ynt k r}z7|j d7_ |j j |j|j |dWYdd}~XnX|t|kr"|j j |j|j|j r|jr|j j|j|jdndS|dkrA||d}n|jj|dS)Nrz#Fatal write error on pipe transportr)rrclearrrrr|rrrrQrrz remove_writerrrZ_maybe_resume_protocolrrr)rr&rr9rrrrs( #  z$_UnixWritePipeTransport._write_readycCsdS)NTr)rrrr can_write_eof sz%_UnixWritePipeTransport.can_write_eofcCsO|jr dSd|_|jsK|jj|j|jj|jdndS)NT)rrrzrr|rr)rrrr write_eof#s    z!_UnixWritePipeTransport.write_eofcCs|jS)N)r)rrrrr,sz"_UnixWritePipeTransport.is_closingcCs*|jdk r&|j r&|jndS)N)r{rr)rrrrr!/sz_UnixWritePipeTransport.closecCs7|jdk r3tjd|t|jjndS)Nzunclosed transport %r)r{rrrr!)rrrrr8sz_UnixWritePipeTransport.__del__cCs|jddS)N)r)rrrrabort=sz_UnixWritePipeTransport.abortzFatal error on pipe transportcCst|ttfrC|jjrrtjd||ddqrn/|jji|d6|d6|d6|jd6|j |dS)Nz%r: %srTrrrfrF) rArConnectionResetErrorrzrrrrrr)rr9rrrrr@s z$_UnixWritePipeTransport._fatal_errorcCsbd|_|jr(|jj|jn|jj|jj|j|jj|j|dS)NT) rrrzrr|rrrr)rr9rrrrNs    z_UnixWritePipeTransport._closec CsDz|jj|Wd|jjd|_d|_d|_XdS)N)rrr{r!rz)rr9rrrrVs    z-_UnixWritePipeTransport._call_connection_lost)rmrnrorrrrrrrrrr!rrrrrrrrr)rrrJs !   !      rJset_inheritablecCsittdd}tj|tj}|sJtj|tj||Bntj|tj||@dS)NZ FD_CLOEXECr)getattrruZF_GETFDZF_SETFD)rsZ inheritableZ cloexec_flagoldrrr_set_inheritablefs rc@seZdZddZdS)rNc Ksd}|tjkr@|jj\}}t|jdntj|d|d|d|d|ddd|||_|dk r|jt |j dd ||j_ ndS) NFrRrSrTrUZuniversal_newlinesrVwb buffering) subprocessPIPErzr rr-Popen_procr!opendetachrS) rr8rRrSrTrUrVrWZstdin_wrrr_startrs  z_UnixSubprocessTransport._startN)rmrnrorrrrrrNps rNc@s^eZdZdZddZddZddZdd 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 tdS)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)rr\r7r8rrrrOs z&AbstractChildWatcher.add_child_handlercCs tdS)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)rr\rrrremove_child_handlersz)AbstractChildWatcher.remove_child_handlercCs tdS)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)rrLrrr attach_loopsz AbstractChildWatcher.attach_loopcCs tdS)zlClose the watcher. This must be called to make sure that any underlying resource is freed. N)r)rrrrr!szAbstractChildWatcher.closecCs tdS)zdEnter the watcher's context and allow starting new processes This function must return selfN)r)rrrr __enter__szAbstractChildWatcher.__enter__cCs tdS)zExit the watcher's contextN)r)rabcrrr__exit__szAbstractChildWatcher.__exit__N) rmrnrorprOrrr!rrrrrrrs    c@sdeZdZddZddZddZddZd d Zd d Zd dZ dS)BaseChildWatchercCs d|_dS)N)rz)rrrrrszBaseChildWatcher.__init__cCs|jddS)N)r)rrrrr!szBaseChildWatcher.closecCs tdS)N)r)r expected_pidrrr _do_waitpidszBaseChildWatcher._do_waitpidcCs tdS)N)r)rrrr_do_waitpid_allsz BaseChildWatcher._do_waitpid_allcCsa|jdk r%|jjtjn||_|dk r]|jtj|j|jndS)N)rzr#r+SIGCHLDr; _sig_chldr)rrLrrrrs   zBaseChildWatcher.attach_loopcCsXy|jWnCtk rS}z#|jjidd6|d6WYdd}~XnXdS)Nz$Unknown exception in SIGCHLD handlerrr)rrQrzr)rr9rrrrs  zBaseChildWatcher._sig_chldcCsAtj|rtj| Stj|r9tj|S|SdS)N)rr WIFSIGNALEDWTERMSIG WIFEXITED WEXITSTATUS)rstatusrrr_compute_returncodes  z$BaseChildWatcher._compute_returncodeN) rmrnrorr!rrrrrrrrrrs       rcseZdZdZfddZfddZddZdd Zd d Zd d Z ddZ ddZ 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) cstji|_dS)N)rr _callbacks)r)rrrrs zSafeChildWatcher.__init__cs|jjtjdS)N)rrrr!)r)rrrr!s zSafeChildWatcher.closecCs|S)Nr)rrrrrszSafeChildWatcher.__enter__cCsdS)Nr)rrrrrrrrszSafeChildWatcher.__exit__cGs$||f|j|<|j|dS)N)rr)rr\r7r8rrrrOsz"SafeChildWatcher.add_child_handlerc Cs/y|j|=dSWntk r*dSYnXdS)NTF)rr=)rr\rrrr$s   z%SafeChildWatcher.remove_child_handlercCs+x$t|jD]}|j|qWdS)N)r"rr)rr\rrrr+sz SafeChildWatcher._do_waitpid_allcCsytj|tj\}}Wn.tk rO|}d}tjd|YnEX|dkr`dS|j|}|jjrtj d||ny|j j |\}}Wn:t k r|jjrtjd|ddnYnX||||dS)Nz8Unknown child process pid %d, will report returncode 255rz$process %s exited with returncode %sz'Child watcher got an unexpected pid: %rrT) rrwaitpidWNOHANGChildProcessErrorrrrrzrrrpopr=)rrr\rr]r7r8rrrr0s*       zSafeChildWatcher._do_waitpid) rmrnrorprr!rrrOrrrrr)rrrs      csveZdZdZfddZfddZddZdd Zd d Zd d Z ddZ 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;tji|_tj|_i|_d|_dS)Nr)rrr threadingZLock_lock_zombies_forks)r)rrrr]s    zFastChildWatcher.__init__cs+|jj|jjtjdS)N)rrrrr!)r)rrrr!ds  zFastChildWatcher.closec Cs'|j|jd7_|SWdQXdS)Nr)rr)rrrrris zFastChildWatcher.__enter__c Csf|jG|jd8_|js,|j r0dSt|j}|jjWdQXtjd|dS)Nrz5Caught subprocesses termination from unknown pids: %s)rrrr1rrr)rrrrZcollateral_victimsrrrros zFastChildWatcher.__exit__cGsf|jGy|jj|}Wn)tk rK||f|j| %dr()rrrrrrrrrr=rrrzrrrr)rr\rr]r7r8rrrrs6             z FastChildWatcher._do_waitpid_all) rmrnrorprr!rrrOrrrr)rrrSs    csdeZdZdZeZfddZddZfddZdd Z d d Z S) _UnixDefaultEventLoopPolicyz:UNIX event loop policy with a watcher for child processes.cstjd|_dS)N)rr_watcher)r)rrrrs z$_UnixDefaultEventLoopPolicy.__init__c CsctjT|jdkrYt|_ttjtjrY|jj|j j qYnWdQXdS)N) rrrrrArcurrent_thread _MainThreadr_localrz)rrrr _init_watchers     z)_UnixDefaultEventLoopPolicy._init_watchercsNtj||jdk rJttjtjrJ|jj|ndS)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)rset_event_looprrArrrr)rrL)rrrrsz*_UnixDefaultEventLoopPolicy.set_event_loopcCs#|jdkr|jn|jS)zzGet the watcher for child processes. If not yet set, a SafeChildWatcher object is automatically created. N)rr)rrrrrMs z-_UnixDefaultEventLoopPolicy.get_child_watchercCs,|jdk r|jjn||_dS)z$Set the watcher for child processes.N)rr!)rrXrrrset_child_watchersz-_UnixDefaultEventLoopPolicy.set_child_watcher) rmrnrorprZ _loop_factoryrrrrMrrr)rrrs   r)2rpr4rrr+rrrrrrrrrrrrr r r r r logr__all__r ImportErrorrZBaseSelectorEventLooprhasattrrtruZ ReadTransportrDZ_FlowControlMixinZWriteTransportrJrrZBaseSubprocessTransportrNrrrrZBaseDefaultEventLoopPolicyrrrrrrrs^             s    F6Ni2