+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| ) rrnr|appendrr}r _test_selector_eventr{ _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)rsreadr}max_sizeBlockingIOErrorInterruptedErrorr/ _fatal_errorrZ data_receivedr{ get_debugrr3r remove_readerrZ eof_received_call_connection_lost)rr&r9rrrrXs# z"_UnixReadPipeTransport._read_readycCs|jj|jdS)N)r{rr})rrrr pause_readingjsz$_UnixReadPipeTransport.pause_readingcCs|jj|j|jdS)N)r{rr}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 exceptionrgrF) rAr/r4ZEIOr{rrdebugcall_exception_handlerrr)rr9rrrrrs! z#_UnixReadPipeTransport._fatal_errorcCs6d|_|jj|j|jj|j|dS)NT)rr{rr}rr)rr9rrrrs z_UnixReadPipeTransport._closec CsDz|jj|Wd|jjd|_d|_d|_XdS)N)rconnection_lostr|r!r{)rr9rrrrs    z,_UnixReadPipeTransport._call_connection_losti)rnrorprrrrrrrr!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)rrrzr|r-r}rsr~rrrrrr.rur_buffer _conn_lostrr{rrsysplatform 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)rrnr|rrr}r rr{rr 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)r{rrr3rrBrokenPipeError)rrrrrs  z#_UnixWritePipeTransport._read_readycCst|tttfs*tt|t|trHt|}n|sRdS|jsd|jr|jtj krt j dn|jd7_dS|j styt j|j|}Wnettfk rd}YnHtk r"}z(|jd7_|j|ddSWYdd}~XnX|t|kr9dS|dkrX||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)rAbytes bytearray memoryviewrareprrrrZ!LOG_THRESHOLD_FOR_CONNLOST_WRITESrwarningrrswriter}rrrQrrr{Z add_writer _write_readyrZ_maybe_pause_protocol)rr&nr9rrrrs4*   z_UnixWritePipeTransport.writecCsgdj|j}|s$td|jjytj|j|}Wn~ttfk rt|jj |Ynt k r}z7|j d7_ |j j |j|j|dWYdd}~XnX|t|kr4|j j |j|j|j r0|jr0|j j|j|jdndS|dkrS||d}n|jj |dS)NzData should not be emptyrz#Fatal write error on pipe transportr)rrraclearrsrr}rrrrQrr{ remove_writerrrZ_maybe_resume_protocolrrr)rr&rr9rrrrs* #  z$_UnixWritePipeTransport._write_readycCsdS)NTr)rrrr can_write_eof sz%_UnixWritePipeTransport.can_write_eofcCs^|jr dS|jstd|_|jsZ|jj|j|jj|jdndS)NT) rr|rarr{rr}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: %srTrrrgrF) rArConnectionResetErrorr{rrrrrr)rr9rrrrr@s z$_UnixWritePipeTransport._fatal_errorcCsbd|_|jr(|jj|jn|jj|jj|j|jj|j|dS)NT) rrr{rr}rrrr)rr9rrrrNs    z_UnixWritePipeTransport._closec CsDz|jj|Wd|jjd|_d|_d|_XdS)N)rrr|r!r{)rr9rrrrVs    z-_UnixWritePipeTransport._call_connection_lost)rnrorprrrrrrrrrr!rrrrrrrrr)rrrJs !   !      rJset_inheritablecCsittdd}tj|tj}|sJtj|tj||Bntj|tj||@dS)NZ FD_CLOEXECr)getattrrvZF_GETFDZF_SETFD)rtZ 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) subprocessPIPEr{r rr-Popen_procr!opendetachrS) rr8rRrSrTrUrVrWZstdin_wrrr_startrs  z_UnixSubprocessTransport._startN)rnrorprrrrrrNps 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) rnrorprqrOrrr!rrrrrrrs    c@sdeZdZddZddZddZddZd d Zd d Zd dZ dS)BaseChildWatchercCs d|_dS)N)r{)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_allcCs|dks$t|tjs$t|jdk rI|jjtjn||_|dk r|jtj|j |j ndS)N) rArZAbstractEventLooprar{r#r+SIGCHLDr; _sig_chldr)rrLrrrrs$  zBaseChildWatcher.attach_loopcCsXy|jWnCtk rS}z#|jjidd6|d6WYdd}~XnXdS)Nz$Unknown exception in SIGCHLD handlerrr)rrQr{r)rr9rrrrs  zBaseChildWatcher._sig_chldcCsAtj|rtj| Stj|r9tj|S|SdS)N)rs WIFSIGNALEDWTERMSIG WIFEXITED WEXITSTATUS)rstatusrrr_compute_returncodes  z$BaseChildWatcher._compute_returncodeN) rnrorprr!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_allcCs|dkstytj|tj\}}Wn.tk ra|}d}tjd|YnEX|dkrrdS|j|}|jj rtj d||ny|j j |\}}Wn:t k r|jj rtjd|ddnYnX||||dS)Nrz8Unknown child process pid %d, will report returncode 255z$process %s exited with returncode %sz'Child watcher got an unexpected pid: %rrT)rarswaitpidWNOHANGChildProcessErrorrrrr{rrrpopr=)rrr\rr]r7r8rrrr0s,       zSafeChildWatcher._do_waitpid) rnrorprqrr!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__cGs{|jstd|jGy|jj|}Wn)tk r`||f|j| %dr()rsrrrrrrrr=rrr{rrrr)rr\rr]r7r8rrrrs6             z FastChildWatcher._do_waitpid_all) rnrorprqrr!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_localr{)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_watchercCsM|dks!t|ts!t|jdk r@|jjn||_dS)z$Set the watcher for child processes.N)rArrarr!)rrXrrrset_child_watchers!z-_UnixDefaultEventLoopPolicy.set_child_watcher) rnrorprqrZ _loop_factoryrrrrMrrr)rrrs   r)2rqr4rsr+rrrrrrrrrrrrr r r r r logr__all__r ImportErrorrZBaseSelectorEventLooprhasattrrurvZ ReadTransportrDZ_FlowControlMixinZWriteTransportrJrrZBaseSubprocessTransportrNrrrrZBaseDefaultEventLoopPolicyrrrrrrrs^             s    F6Ni2