o bk@sdZddlZddlZddlZddlZddlZddlmZddlm Z m Z m Z m Z ddl mZmZmZddlmZmZddlmZmZmZmZmZmZmZmZmZmZddlm Z m!Z!dd l"m#Z#m$Z$m%Z%dd l&m'Z'm(Z(e)d Z*e)d Z+zdd l,m-Z.Wn e/ydZ-Ynwe.Z-zddl m0Z1Wn e/ydZ0Ynwe1Z0e(dkZ2dZ3e2rddl m4Z4m5Z5m6Z6m7Z7dZ3e'8rzddl9Z9dZ3Wn e/ydZ9YnwGddde Z:e e:Gddde$j;Ze(dkre>Z?ne}, used to wake up the main loop from another thread or a signal handler. This is why we have wakeUp together with doRead This is used by threads or signals to wake up the event loop. cCdS)z: Called when the event should be wake up. Nr'r'r'}, implemented using a pair of sockets rather than pipes (due to the lack of support in select() on Windows for pipes), used to wake up the main loop from another thread. rcCs||_ttjtj}|tjtjdtttjtj}| d| d| | | \}}Wdn1sAwY|d|d||_||_|jj|_dS) Initialize.)z 127.0.0.1rNr)reactorsocketAF_INET SOCK_STREAM setsockopt IPPROTO_TCP TCP_NODELAY contextlibclosingbindlistenconnect getsocknameaccept setblockingrwfileno)selfr7clientserverreader clientaddrr'r'r(__init__rs"    z_SocketWaker.__init__c CsPz t|jjdWdSty'}z|jdtjkrWYd}~dSd}~ww)zSend a byte to my connection.xrN)runtilConcludesrGsendOSErrorargserrnoWSAEWOULDBLOCKrIer'r'r(r)sz_SocketWaker.wakeUpcCs(z |jdWdStyYdSw)z4 Read some data from my connection. N)rFrecvrRrIr'r'r(r+s  z_SocketWaker.doReadcCs|j|jdSN)rFcloserG)rIr,r'r'r(r-s z_SocketWaker.connectionLostN) r.r/r0r1r2rNr)r+r-r'r'r'r(r4gs r4c@s4eZdZdZdZdZdZddZddZdd Z dS) _FDWakera The I{self-pipe trick}, used to wake up the main loop from another thread or a signal handler. L{_FDWaker} is a base class for waker implementations based on writing to a pipe being monitored by the reactor. @ivar o: The file descriptor for the end of the pipe which can be written to wake up a reactor monitoring this waker. @ivar i: The file descriptor which should be monitored in order to be awoken by this waker. rNcsX|_t\__tjtjtjtjfdd_dS)r5csjSr[)ir'rZr'r(sz#_FDWaker.__init__..N) r7ospiper^or!setNonBlocking_setCloseOnExecrHrIr7r'rZr(rNs    z_FDWaker.__init__cCst|dddS)zA Read some bytes from the pipe and discard them. cSsdSr[r')datar'r'r(r_r*z!_FDWaker.doRead..N)r! readFromFDrHrZr'r'r(r+sz_FDWaker.doReadc CsLt|dsdS|j|jfD]}zt|Wq tyYq w|`|`dS)zClose both ends of my pipe.rbN)hasattrr^rbr`r\rR)rIr,fdr'r'r(r-s   z_FDWaker.connectionLost) r.r/r0r1r2r^rbrNr+r-r'r'r'r(r]s r]c@eZdZdZddZdS) _UnixWakerz This class provides a simple interface to wake up the event loop. This is used by threads or signals to wake up the event loop. c Cs\|jdur,z ttj|jdWdSty+}z|jtjkr WYd}~dSd}~wwdS)z)Write one byte to the pipe, and flush it.NrO)rbrrPr`writerRrTEAGAINrVr'r'r(r)s  z_UnixWaker.wakeUpN)r.r/r0r1r)r'r'r'r(rks rkc@s0eZdZdZddZddZddZdd Zd S) _SIGCHLDWakerz} L{_SIGCHLDWaker} can wake up a reactor whenever C{SIGCHLD} is received. @see: L{twisted.internet._signals} cCst||dSr[)r]rNrer'r'r(rNsz_SIGCHLDWaker.__init__cCst|jdS)zJ Install the handler necessary to make this waker active. N)r installHandlerrbrZr'r'r(installsz_SIGCHLDWaker.installcCstddS)zC Remove the handler which makes this waker active. N)r rorZr'r'r( uninstallsz_SIGCHLDWaker.uninstallcCst|tdS)a Having woken up the reactor in response to receipt of C{SIGCHLD}, reap the process which exited. This is called whenever the reactor notices the waker pipe is writeable, which happens soon after any call to the C{wakeUp} method. N)r]r+r"reapAllProcessesrZr'r'r(r+s z_SIGCHLDWaker.doReadN)r.r/r0r1rNrprrr+r'r'r'r(rns  rnc@s<eZdZdZejeeejeeifddZ dS)_DisconnectSelectableMixinz> Mixin providing the C{_disconnectSelectable} method. cCsx||||j}|r-|r!|jtjkr!t|r!||dS||| |dS||| t |dS)z Utility function for disconnecting a selectable. Supports half-close notification, isRead should be boolean indicating whether error resulted from doRead(). N) removeReaderget __class__rConnectionDoner providedByreadConnectionLost removeWriterr-rr3)rI selectablewhyisReadfaildictfr'r'r(_disconnectSelectables     z0_DisconnectSelectableMixin._disconnectSelectableN) r.r/r0r1rrxrr3ConnectionLostrr'r'r'r(rt s  rtc@seZdZUdZeZddZdZddZddZ d idddd dfd d Z d0ddZ d1ddZ d2ddZ d3ddZd4ddZ d5ddZerUejejejfZeejed<nejejfZd d!Zd"d#Z d6d$d%Zd7d&d'Zd8d(d)Z d8d*d+Zd7d,d-Z d.d/Z!dS)9PosixReactorBasez A basis for reactors that use file descriptors. @ivar _childWaker: L{None} or a reference to the L{_SIGCHLDWaker} which is used to properly notice child process termination. cCs4|js|||_|j|j||jdSdS)z Install a `waker' to allow threads and signals to wake up the IO thread. We use the self-pipe trick (http://cr.yp.to/docs/selfpipe.html) to wake the reactor. On Windows we use a pair of sockets. N)waker _wakerFactory_internalReadersadd addReaderrZr'r'r( installWaker?s  zPosixReactorBase.installWakerNcCs^t|tdkr+tr-|js t||_|j|j||j|j t dSdSdS)z Extend the basic signal handling logic to also support handling SIGCHLD to know when to try to reap child processes. rN) r _handleSignalsrprocessEnabled _childWakerrnrrrrpr"rsrZr'r'r(rMs      zPosixReactorBase._handleSignalscCs|jr |jdSdS)a If a child waker was created and installed, uninstall it now. Since this disables reactor functionality and is only called when the reactor is stopping, it doesn't provide any directly useful functionality, but the cleanup of reactor-related process-global state that it does helps in unit tests involving multiple reactors and is generally just a nice thing. N)rrrrZr'r'r(_uninstallHandler`sz"PosixReactorBase._uninstallHandlerr'rc Cstdkr(|r| durtdt||||||||| St||||||||| Stdkr]|dur4td|durrTr`r8rtypingrzope.interfacerrrrtwisted.internetrrr twisted.internet.baser r twisted.internet.interfacesr r rrrrrrrrtwisted.internet.mainrrtwisted.pythonrrrtwisted.python.runtimerrConnectionFdescWentAway _NO_FILENOrtwisted.protocolsr_tls ImportErrorr_sslrrr r!r"r# isWindowsrr$Loggerr4r]rkrrnrtrrrgetattr__all__r'r'r'r(s 0      30 $ &AI