
    Vh(T                       d Z ddlm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mZ dd	lmZmZ dd
l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jZ                  d      Z.	 ddl/m0Z1 e1Z0	 ddl
m3Z4 e4Z3e&dk(  Z5dZ6e5r
ddl
m7Z7m8Z8 dZ6 e%jr                         r	 ddl:Z:dZ6 G d d      Z; e	eee       G d de;e             Z< G d d      Z= e	e       G d de=e;             Z>e0e3	 ee<e       e5r
 ee<ee       e6r	 ee<e        e?edd      	 ee<e       dgZ@y# e2$ r dZ0Y w xY w# e2$ r dZ3Y w xY w# e2$ r dZ:Y w xY w)z
Posix reactor base class
    )annotationsN)Sequence)classImplementsimplementer)errortcpudp)ReactorBase)
IConnectorIHalfCloseableDescriptorIReactorFDSetIReactorMulticastIReactorProcessIReactorSocketIReactorSSLIReactorTCPIReactorUDPIReactorUNIXIReactorUNIXDatagram)CONNECTION_DONECONNECTION_LOST)ClientFactory)failurelog)platformplatformType   )SignalHandling_ChildSignalHandling_IWaker_MultiSignalHandling_Wakerz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         J/home/dcms/DCMS/lib/python3.12/site-packages/twisted/internet/posixbase.py_disconnectSelectablez0_DisconnectSelectableMixin._disconnectSelectableU   s      	*%LL'MMU%9%99,77
C--a0!!*-))!,j)%%gooc&:;    N)
__name__
__module____qualname____doc__r   r.   r   r3   ConnectionLostr;    r<   r:   r)   r)   P   sW       /'//2F%2F2F2H"I  /'//2F%2F2F2H"I
<r<   r)   c                  b    e Zd ZU dZdZddZd Zd 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r)ej"                  ej$                  ej&                  fZded<   nej"                  ej$                  fZd Zd Z	 d!dZd"dZ	 	 d#	 	 	 	 	 	 	 	 	 	 	 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.
    Nc                    t               S N)r"   r4   s    r:   _wakerFactoryzPosixReactorBase._wakerFactory   s	    xr<   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)wakerrH   _internalReadersadd	addReaderrG   s    r:   installWakerzPosixReactorBase.installWaker   sH     zz++-DJ!!%%djj1NN4::& r<   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)r4   baseHandlingr-   s     r:   rQ   z PosixReactorBase._signalsFactory   sS    
 w.07"' !(//22	
 
 r<   rB   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&   
PTYProcessrW   win32processtwisted.internet._dumbwin32procNotImplementedError)r4   processProtocol
executableargsenvpathuidgidusePTYchildFDsrW   s              r:   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 r<   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)r4   portprotocol	interfacemaxPacketSizeps         r:   	listenUDPzPosixReactorBase.listenUDP   s+    
 HHT8YtD	r<   c                Z    t        j                  ||||| |      }|j                          |S )zConnects a given DatagramProtocol to the given numeric UDP port.

        EXPERIMENTAL.

        @returns: object conforming to IListeningPort.
        )r	   MulticastPortri   )r4   rj   rk   rl   rm   listenMultiplern   s          r:   listenMulticastz PosixReactorBase.listenMulticast   s4     (I}dN
 	
r<   c                r    t         sJ d       t        j                  |||| |      }|j                          |S NUNIX support is not present)unixEnabledr'   	Connectorconnect)r4   addressfactorytimeoutcheckPIDcs         r:   connectUNIXzPosixReactorBase.connectUNIX  s4    999{NN7GWdHE			r<   c                t    t         sJ d       t        j                  ||||| |      }|j                          |S ru   )rw   r'   rh   ri   )r4   rz   r{   backlogmodewantPIDrn   s          r:   
listenUNIXzPosixReactorBase.listenUNIX  s9    999{IIgwtWE	r<   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}.
        rv   )rw   r'   DatagramPortri   )r4   rz   rk   rm   r   rn   s         r:   listenUNIXDatagramz#PosixReactorBase.listenUNIXDatagram  s;     999{gxdK	r<   c                t    t         sJ d       t        j                  ||||||       }|j                          |S )zd
        Connects a L{ConnectedDatagramProtocol} instance to a path.

        EXPERIMENTAL.
        rv   )rw   r'   ConnectedDatagramPortri   )r4   rz   rk   rm   r   bindAddressrn   s          r:   connectUNIXDatagramz$PosixReactorBase.connectUNIXDatagram  sB     999{&&X}dK
 	
r<   zSequence[socket.AddressFamily]_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   UnsupportedAddressFamilyrw   socketAF_UNIXr'   rh   _fromListeningDescriptorr   ri   )r4   fileDescriptoraddressFamilyr{   rn   s        r:   adoptStreamPortz PosixReactorBase.adoptStreamPort:  sy      > >>00??=FNN:		224QA11nmWA 	
r<   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   rw   r   r   r'   Server_fromConnectedSocketr   )r4   r   r   r{   s       r:   adoptStreamConnectionz&PosixReactorBase.adoptStreamConnectionO  sj    
  > >>00??=FNN:;;33NGTRR::22w r<   c                    |t         j                  t         j                  fvrt        j                  |      t
        j                  j                  | ||||      }|j                          |S )N)rm   )	r   AF_INETAF_INET6r   r   r	   rh   r   ri   )r4   r   r   rk   rm   rn   s         r:   adoptDatagramPortz"PosixReactorBase.adoptDatagramPort^  sa      AA00??HH--.- . 
 	
r<   c                X    t        j                  |||||       }|j                          |S rF   )r   rh   ri   )r4   rj   r{   r   rl   rn   s         r:   	listenTCPzPosixReactorBase.listenTCPl  s)    HHT7GY=	r<   c                Z    t        j                  ||||||       }|j                          |S rF   )r   rx   ry   )r4   hostrj   r{   r|   r   r~   s          r:   
connectTCPzPosixReactorBase.connectTCPq  s*     MM$gwTJ			r<   c           	         t         ,t         j                  |d|      }| j                  |||||      S t        -t        j	                  |||||||       }|j                          |S J d       )NTSSL support is not present)r#   TLSMemoryBIOFactoryr   r$   rx   ry   )	r4   r   rj   r{   contextFactoryr|   r   
tlsFactoryr~   s	            r:   
connectSSLzPosixReactorBase.connectSSL  sq     ?00wOJ??4z7KPP_dG^Wk4A IIKH6665r<   c                    t         4t         j                  |d|      }| j                  ||||      }d|_        |S t        ,t        j                  ||||||       }|j                          |S J d       )NFTLSr   )r#   r   r   _typer$   rh   ri   )r4   rj   r{   r   r   rl   r   rn   s           r:   	listenSSLzPosixReactorBase.listenSSL  st    ?00PJ>>$
GYGDDJK_wDQAH6665r<   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.
        )setrK   r+   r1   list)r4   readerswritersremovedReadersreaderremovedWriterswriters          r:   
_removeAllzPosixReactorBase._removeAll  so     W(=(==$ 	&Ff%	& W$ 	&Ff%	& N^344r<   )returnr    )r   r   )     )r   r   F)   r   )2     r   )r   r   )r   r   N)r   )r   r   )g      >@N)r   strrj   intr{   z'ClientFactory'r|   floatr   ztuple[str, int] | Noner   r   )r   N)r=   r>   r?   r@   _childWakerrH   rN   rQ   rf   ro   rs   r   r   r   r   rw   r   r   r   r   r   __annotations__r   r   r   r   r   r   r   r   __classcell__)r-   s   @r:   rD   rD   v   s"    K
'< 6t PU" NR" NNOONNE
!#A 	
 NNOO%
!
*  FJ
 .2

 
 !	

 
 ,
 

 LP775r<   rD   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   errr;   )r4   r5   fdeventr6   inReads         r:   _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   rB   r<   r:   r   r     s    7@r<   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 rF   )_reactor_loopr   _readers_writers)r4   reactors     r:   __init__z_ContinuousPolling.__init__  s"    
r<   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)r4   r   r   s      r:   
_checkLoopz_ContinuousPolling._checkLoop  s    
 ==DMMzz!G(6
#'==

  

  u 5 " ZZJJOODJ r<   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   )r4   r   r   s      r:   r   z_ContinuousPolling.iterate/  sb     4==) 	?F>	?4==) 	@F?	@r<   c                Z    | j                   j                  |       | j                          y)zU
        Add a C{FileDescriptor} for notification of data available to read.
        N)r   rL   r   r4   r   s     r:   rM   z_ContinuousPolling.addReader8        	&!r<   c                Z    | j                   j                  |       | j                          y)zV
        Add a C{FileDescriptor} for notification of data available to write.
        N)r   rL   r   r4   r   s     r:   	addWriterz_ContinuousPolling.addWriter?  r   r<   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     r:   r+   z_ContinuousPolling.removeReaderF  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     r:   r1   z_ContinuousPolling.removeWriterP  s9    
	MM  ( 	  		r   c                    t        | j                  | j                  z        }| j                  j                          | j                  j                          |S )z1
        Remove all readers and writers.
        )r   r   r   clear)r4   results     r:   	removeAllz_ContinuousPolling.removeAll[  sB     dmmdmm34 	r<   c                ,    t        | j                        S )z/
        Return a list of the readers.
        )r   r   rG   s    r:   
getReadersz_ContinuousPolling.getReadersf       DMM""r<   c                ,    t        | j                        S )z/
        Return a list of the writers.
        )r   r   rG   s    r:   
getWritersz_ContinuousPolling.getWritersl  r   r<   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   r4   r   s     r:   	isReadingz_ContinuousPolling.isReadingr       T]]""r<   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     r:   	isWritingz_ContinuousPolling.isWriting  r  r<   N)r=   r>   r?   r@   r   r   r   r   r   r   rM   r   r+   r1   r   r   r   r  r  rB   r<   r:   r   r     sV    , HI$@		####r<   r   fromfd)Ar@   
__future__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   r   twisted.internet.mainr   r   twisted.internet.protocolr   twisted.pythonr   r   twisted.python.runtimer   r   _signalsr   r   r    r!   r"   ConnectionFdescWentAwayr   twisted.protocolsr#   _tlsImportErrorr$   _sslrw   processEnabledr&   r'   	isWindowsrZ   r)   rD   r   r   getattr__all__rB   r<   r:   <module>r     s  
 #  
  7 , , -    C 3 ' 9  -u,,-CD- C, Cg%.N 8
#< #<L [+'89x51; x5 :x5v	F@ F@R ]N#)C N# N#b ?co$k2$l4HI$o6
68T".$n5
I  
C  
C&  s6   E E >E EEEEE'&E'