
    ϪfS                        d Z ddlZddlZddlmZ ddlmZmZ ddlm	Z	m
Z
mZ ddlmZ ddlmZmZmZmZmZmZmZmZmZmZ ddlmZmZ dd	lmZmZ dd
lm Z m!Z! ddl"m#Z#m$Z$m%Z%m&Z&m'Z'  e	jP                  d      Z) e	jP                  d      Z*	 ddl+m,Z- e-Z,	 ddlm/Z0 e0Z/e!dk(  Z1dZ2e1r
ddlm3Z3m4Z4 dZ2 e jj                         r	 ddl6Z6dZ2 G d d      Z7 eeee       G d de7e             Z8 G d d      Z9 ee       G d de9e7             Z:e,e/	 ee8e       e1r
 ee8ee       e2r	 ee8e        e;edd      	 ee8e       dgZ<y# e.$ r dZ,Y w xY w# e.$ r dZ/Y w xY w# e.$ r dZ6Y w xY w)z
Posix reactor base class
    N)Sequence)classImplementsimplementer)errortcpudp)ReactorBase)
IHalfCloseableDescriptorIReactorFDSetIReactorMulticastIReactorProcessIReactorSocketIReactorSSLIReactorTCPIReactorUDPIReactorUNIXIReactorUNIXDatagram)CONNECTION_DONECONNECTION_LOST)failurelog)platformplatformType   )SignalHandling_ChildSignalHandling_IWaker_MultiSignalHandling_WakerzHandler has no fileno methodzFile descriptor lost)tls)sslposixF)processunixTc                       e Zd ZdZej
                   ej                   ej
                               ej                   ej                   ej                               ifdZ	y)_DisconnectSelectableMixinz>
    Mixin providing the C{_disconnectSelectable} method.
    c                    | j                  |       |j                  |j                        }|ri|rD|j                  t        j                  k(  r't        j                  |      r|j                  |       y| j                  |       |j                  |       y| j                  |       |j                  t        j                  |             y)z
        Utility function for disconnecting a selectable.

        Supports half-close notification, isRead should be boolean indicating
        whether error resulted from doRead().
        N)removeReaderget	__class__r   ConnectionDoner
   
providedByreadConnectionLostremoveWriterconnectionLostr   Failure)self
selectablewhyisReadfaildictfs         </usr/lib/python3/dist-packages/twisted/internet/posixbase.py_disconnectSelectablez0_DisconnectSelectableMixin._disconnectSelectableS   s      	*%LL'MMU%9%99,77
C--a0!!*-))!,j)%%gooc&:;    N)
__name__
__module____qualname____doc__r   r+   r   r0   ConnectionLostr8    r9   r7   r&   r&   N   sW       /'//2F%2F2F2H"I  /'//2F%2F2F2H"I
<r9   r&   c                   h    e Zd ZU dZdZdefdZd Zdef fdZ	di dddddfd	Z
dd
Z	 ddZddZddZddZ	 ddZer6ej&                  ej(                  ej*                  fZeej0                     ed<   nej&                  ej(                  fZd Zd Z	 ddZd dZd!dZ	 d!dZd dZ d Z! xZ"S )"PosixReactorBasez
    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.
    Nreturnc                     t               S N)r   r1   s    r7   _wakerFactoryzPosixReactorBase._wakerFactory   s	    xr9   c                     | j                   sV| j                         | _         | j                  j                  | j                          | j	                  | j                          yy)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)wakerrF   _internalReadersadd	addReaderrE   s    r7   installWakerzPosixReactorBase.installWaker   sH     zz++-DJ!!%%djj1NN4::& r9   c                     t         |          }t        dk(  r+t        |t	        | j
                  | j                        f      S |S )zj
        Customize reactor signal handling to support child processes on POSIX
        platforms.
        r"   )super_signalsFactoryr   r   r   _addInternalReader_removeInternalReader)r1   baseHandlingr*   s     r7   rO   z PosixReactorBase._signalsFactory   sS    
 w.07"' !(//22	
 
 r9   r?   r   c
                 ~   t         dk(  rI|r*|	t        d      t        j                  | ||||||||	      S t        j                  | ||||||||		      S t         dk(  rX|t        d      |t        d      |rt        d      |	rt        d      t
        rdd	lm}
  |
| |||||      S t        d
      t        d      )Nr"   z1Using childFDs is not supported with usePTY=True.win32z,Setting UID is unsupported on this platform.z,Setting GID is unsupported on this platform.z1The usePTY parameter is not supported on Windows.z1Customizing childFDs is not supported on Windows.r   )Processz:spawnProcess not available since pywin32 is not installed.z0spawnProcess only available on Windows or POSIX.)r   
ValueErrorr#   
PTYProcessrU   win32processtwisted.internet._dumbwin32procNotImplementedError)r1   processProtocol
executableargsenvpathuidgidusePTYchildFDsrU   s              r7   spawnProcesszPosixReactorBase.spawnProcess   s    7"'$K  ))*dCSRX  #
 
 W$ !OPP !OPP !TUU !TUUCt_j$TRR)P  &B r9   c                 X    t        j                  |||||       }|j                          |S )zConnects a given L{DatagramProtocol} to the given numeric UDP port.

        @returns: object conforming to L{IListeningPort}.
        )r   PortstartListening)r1   portprotocol	interfacemaxPacketSizeps         r7   	listenUDPzPosixReactorBase.listenUDP   s+    
 HHT8YtD	r9   c                 Z    t        j                  ||||| |      }|j                          |S )zConnects a given DatagramProtocol to the given numeric UDP port.

        EXPERIMENTAL.

        @returns: object conforming to IListeningPort.
        )r   MulticastPortrg   )r1   rh   ri   rj   rk   listenMultiplerl   s          r7   listenMulticastz PosixReactorBase.listenMulticast   s4     (I}dN
 	
r9   c                 r    t         sJ d       t        j                  |||| |      }|j                          |S NUNIX support is not present)unixEnabledr$   	Connectorconnect)r1   addressfactorytimeoutcheckPIDcs         r7   connectUNIXzPosixReactorBase.connectUNIX   s4    999{NN7GWdHE			r9   c                 t    t         sJ d       t        j                  ||||| |      }|j                          |S rs   )ru   r$   rf   rg   )r1   rx   ry   backlogmodewantPIDrl   s          r7   
listenUNIXzPosixReactorBase.listenUNIX  s9    999{IIgwtWE	r9   c                 r    t         sJ d       t        j                  |||||       }|j                          |S )z
        Connects a given L{DatagramProtocol} to the given path.

        EXPERIMENTAL.

        @returns: object conforming to L{IListeningPort}.
        rt   )ru   r$   DatagramPortrg   )r1   rx   ri   rk   r   rl   s         r7   listenUNIXDatagramz#PosixReactorBase.listenUNIXDatagram  s;     999{gxdK	r9   c                 t    t         sJ d       t        j                  ||||||       }|j                          |S )zd
        Connects a L{ConnectedDatagramProtocol} instance to a path.

        EXPERIMENTAL.
        rt   )ru   r$   ConnectedDatagramPortrg   )r1   rx   ri   rk   r   bindAddressrl   s          r7   connectUNIXDatagramz$PosixReactorBase.connectUNIXDatagram  sB     999{&&X}dK
 	
r9   _supportedAddressFamiliesc                 &   || j                   vrt        j                  |      t        r5|t        j
                  k(  r"t        j                  j                  | ||      }n"t        j                  j                  | |||      }|j                          |S )a0  
        Create a new L{IListeningPort} from an already-initialized socket.

        This just dispatches to a suitable port implementation (eg from
        L{IReactorTCP}, etc) based on the specified C{addressFamily}.

        @see: L{twisted.internet.interfaces.IReactorSocket.adoptStreamPort}
        )r   r   UnsupportedAddressFamilyru   socketAF_UNIXr$   rf   _fromListeningDescriptorr   rg   )r1   fileDescriptoraddressFamilyry   rl   s        r7   adoptStreamPortz PosixReactorBase.adoptStreamPort8  sy      > >>00??=FNN:		224QA11nmWA 	
r9   c                     || j                   vrt        j                  |      t        r4|t        j
                  k(  r!t        j                  j                  |||       S t        j                  j                  ||||       S )zg
        @see:
            L{twisted.internet.interfaces.IReactorSocket.adoptStreamConnection}
        )
r   r   r   ru   r   r   r$   Server_fromConnectedSocketr   )r1   r   r   ry   s       r7   adoptStreamConnectionz&PosixReactorBase.adoptStreamConnectionM  sj    
  > >>00??=FNN:;;33NGTRR::22w r9   c                     |t         j                  t         j                  fvrt        j                  |      t
        j                  j                  | ||||      }|j                          |S )N)rk   )	r   AF_INETAF_INET6r   r   r   rf   r   rg   )r1   r   r   ri   rk   rl   s         r7   adoptDatagramPortz"PosixReactorBase.adoptDatagramPort\  sa      AA00??HH--.- . 
 	
r9   c                 X    t        j                  |||||       }|j                          |S rD   )r   rf   rg   )r1   rh   ry   r   rj   rl   s         r7   	listenTCPzPosixReactorBase.listenTCPj  s)    HHT7GY=	r9   c                 Z    t        j                  ||||||       }|j                          |S rD   )r   rv   rw   )r1   hostrh   ry   rz   r   r|   s          r7   
connectTCPzPosixReactorBase.connectTCPo  s(    MM$gwTJ			r9   c           	          t         ,t         j                  |d|      }| j                  |||||      S t        -t        j	                  |||||||       }|j                          |S J d       )NTSSL support is not present)r    TLSMemoryBIOFactoryr   r!   rv   rw   )	r1   r   rh   ry   contextFactoryrz   r   
tlsFactoryr|   s	            r7   
connectSSLzPosixReactorBase.connectSSLv  sq     ?00wOJ??4z7KPP_dG^Wk4A IIKH6665r9   c                     t         4t         j                  |d|      }| j                  ||||      }d|_        |S t        ,t        j                  ||||||       }|j                          |S J d       )NFTLSr   )r    r   r   _typer!   rf   rg   )r1   rh   ry   r   r   rj   r   rl   s           r7   	listenSSLzPosixReactorBase.listenSSL  st    ?00PJ>>$
GYGDDJK_wDQAH6665r9   c                     t        |      | j                  z
  }|D ]  }| j                  |        t        |      }|D ]  }| j                  |        t	        ||z        S )ag  
        Remove all readers and writers, and list of removed L{IReadDescriptor}s
        and L{IWriteDescriptor}s.

        Meant for calling from subclasses, to implement removeAll, like::

          def removeAll(self):
              return self._removeAll(self._reads, self._writes)

        where C{self._reads} and C{self._writes} are iterables.
        )setrI   r(   r.   list)r1   readerswritersremovedReadersreaderremovedWriterswriters          r7   
_removeAllzPosixReactorBase._removeAll  so     W(=(==$ 	&Ff%	& W$ 	&Ff%	& N^344r9   )     )r   r   F)   r   )2     r   )r   r   )r   r   N)r   )r   r   )r   N)#r:   r;   r<   r=   _childWakerr   rF   rL   r   rO   rd   rm   rq   r}   r   r   r   ru   r   r   r   r   r   r   AddressFamily__annotations__r   r   r   r   r   r   r   r   __classcell__)r*   s   @r7   rA   rA   t   s     Kw 
' < 6t PU" NR" NNOONNE
!8F,@,@#A 	
 NNOO%
!
*  FJ

 LP775r9   rA   c                       e Zd ZdZd Zy)_PollLikeMixina  
    Mixin for poll-like reactors.

    Subclasses must define the following attributes::

      - _POLL_DISCONNECTED - Bitmask for events indicating a connection was
        lost.
      - _POLL_IN - Bitmask for events indicating there is input to read.
      - _POLL_OUT - Bitmask for events indicating output can be written.

    Must be mixed in to a subclass of PosixReactorBase (for
    _disconnectSelectable).
    c                    d}d}|| j                   z  r-|| j                  z  s|| j                  v r	d}t        }nft        }n_	 |j                         dk(  rt        }nD|| j                  z  r|j                         }d}|s!|| j                  z  r|j                         }d}|r| j                  |||       yy# t        $ r. t        j                         d   }t        j                          Y Mw xY w)zg
        fd is available for read or write, do the work and raise errors if
        necessary.
        NFTr   )_POLL_DISCONNECTED_POLL_IN_readsr   r   fileno_NO_FILEDESCdoRead	_POLL_OUTdoWriteBaseExceptionsysexc_infor   errr8   )r1   r2   fdeventr3   inReads         r7   _doReadOrWritez_PollLikeMixin._doReadOrWrite  s    
 4***EDMM4I T[[ 
 % & $$&", 'Ct}},(//1!%54>>#9 )002!& &&z3?  !  llnQ'		s   AB7 74C.-C.N)r:   r;   r<   r=   r   r?   r9   r7   r   r     s    7@r9   r   c                   d    e Zd ZdZdZdZdZd Zd Zd Z	d Z
d	 Zd
 Zd Zd Zd Zd Zd Zd Zy)_ContinuousPollinga  
    Schedule reads and writes based on the passage of time, rather than
    notification.

    This is useful for supporting polling filesystem files, which C{epoll(7)}
    does not support.

    The implementation uses L{_PollLikeMixin}, which is a bit hacky, but
    re-implementing and testing the relevant code yet again is unappealing.

    @ivar _reactor: The L{EPollReactor} that is using this instance.

    @ivar _loop: A C{LoopingCall} that drives the polling, or L{None}.

    @ivar _readers: A C{set} of C{FileDescriptor} objects that should be read
        from.

    @ivar _writers: A C{set} of C{FileDescriptor} objects that should be
        written to.
    r         c                 \    || _         d | _        t               | _        t               | _        y rD   )_reactor_loopr   _readers_writers)r1   reactors     r7   __init__z_ContinuousPolling.__init__  s"    
r9   c                 Z   | j                   s| j                  re| j                  Xddlm}m}  || j                        | _        | j                  | j                  _        | j                  j                  |d       yy| j                  r"| j                  j                          d| _        yy)zh
        Start or stop a C{LoopingCall} based on whether there are readers and
        writers.
        Nr   )_EPSILONLoopingCallF)now)r   r   r   twisted.internet.taskr   r   iterater   clockstartstop)r1   r   r   s      r7   
_checkLoopz_ContinuousPolling._checkLoop  s    
 ==DMMzz!G(6
#'==

  

  u 5 " ZZJJOODJ r9   c                     t        | j                        D ]  }| j                  ||| j                         ! t        | j                        D ]  }| j                  ||| j
                         ! y)zX
        Call C{doRead} and C{doWrite} on all readers and writers respectively.
        N)r   r   r   r   r   r   )r1   r   r   s      r7   r   z_ContinuousPolling.iterate&  sb     4==) 	?F>	?4==) 	@F?	@r9   c                 Z    | j                   j                  |       | j                          y)zU
        Add a C{FileDescriptor} for notification of data available to read.
        N)r   rJ   r   r1   r   s     r7   rK   z_ContinuousPolling.addReader/        	&!r9   c                 Z    | j                   j                  |       | j                          y)zV
        Add a C{FileDescriptor} for notification of data available to write.
        N)r   rJ   r   r1   r   s     r7   	addWriterz_ContinuousPolling.addWriter6  r   r9   c                 z    	 | j                   j                  |       | j                          y# t        $ r Y yw xY w)zY
        Remove a C{FileDescriptor} from notification of data available to read.
        N)r   removeKeyErrorr   r   s     r7   r(   z_ContinuousPolling.removeReader=  s9    	MM  ( 	  		   . 	::c                 z    	 | j                   j                  |       | j                          y# t        $ r Y yw xY w)zb
        Remove a C{FileDescriptor} from notification of data available to
        write.
        N)r   r   r   r   r   s     r7   r.   z_ContinuousPolling.removeWriterG  s9    
	MM  ( 	  		r   c                     t        | j                  | j                  z        }| j                  j                          | j                  j                          |S )z1
        Remove all readers and writers.
        )r   r   r   clear)r1   results     r7   	removeAllz_ContinuousPolling.removeAllR  sB     dmmdmm34 	r9   c                 ,    t        | j                        S )z/
        Return a list of the readers.
        )r   r   rE   s    r7   
getReadersz_ContinuousPolling.getReaders]       DMM""r9   c                 ,    t        | j                        S )z/
        Return a list of the writers.
        )r   r   rE   s    r7   
getWritersz_ContinuousPolling.getWritersc  r   r9   c                     || j                   v S )aj  
        Checks if the file descriptor is currently being observed for read
        readiness.

        @param fd: The file descriptor being checked.
        @type fd: L{twisted.internet.abstract.FileDescriptor}
        @return: C{True} if the file descriptor is being observed for read
            readiness, C{False} otherwise.
        @rtype: C{bool}
        )r   r1   r   s     r7   	isReadingz_ContinuousPolling.isReadingi       T]]""r9   c                     || j                   v S )al  
        Checks if the file descriptor is currently being observed for write
        readiness.

        @param fd: The file descriptor being checked.
        @type fd: L{twisted.internet.abstract.FileDescriptor}
        @return: C{True} if the file descriptor is being observed for write
            readiness, C{False} otherwise.
        @rtype: C{bool}
        )r   r   s     r7   	isWritingz_ContinuousPolling.isWritingv  r   r9   N)r:   r;   r<   r=   r   r   r   r   r   r   rK   r   r(   r.   r   r   r   r   r   r?   r9   r7   r   r     sV    , HI$@		####r9   r   fromfd)=r=   r   r   typingr   zope.interfacer   r   twisted.internetr   r   r   twisted.internet.baser	   twisted.internet.interfacesr
   r   r   r   r   r   r   r   r   r   twisted.internet.mainr   r   twisted.pythonr   r   twisted.python.runtimer   r   _signalsr   r   r   r   r   ConnectionFdescWentAway
_NO_FILENOr   twisted.protocolsr    _tlsImportErrorr!   _sslru   processEnabledr#   r$   	isWindowsrX   r&   rA   r   r   getattr__all__r?   r9   r7   <module>r     s  

  
  7 , , -   C ' 9  +U**+IJ
,u,,-CD- C, Cg%.N 8
#< #<L [+'89q51; q5 :q5h	F@ F@R ]N#)C N# N#b ?co$k2$l4HI$o6
68T".$n5
{  
C  
C&  s6   E E E! EEEE!E+*E+