U
    �AcjB*  ã                
   @   s
  d Z ddlZddlZddl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 z6eedƒZeedƒZeed	ƒZeed
ƒZeedƒZW n* ek
r¼ Z zeeƒ‚W 5 dZ[X Y nX G dd„ deƒZe ee¡ eeeƒG dd„ de
jƒƒZdd„ ZddgZdS )am  
A kqueue()/kevent() based implementation of the Twisted main loop.

To use this reactor, start your application specifying the kqueue reactor::

   twistd --reactor kqueue ...

To install the event loop from code (and you should do this before any
connections, listeners or connectors are added)::

   from twisted.internet import kqreactor
   kqreactor.install()
é    N)Ú	AttributeÚ	InterfaceÚdeclarationsÚimplementer)ÚmainÚ	posixbase)ÚIReactorDaemonizeÚIReactorFDSet)ÚfailureÚlogÚ	KQ_EV_ADDÚKQ_EV_DELETEÚ	KQ_EV_EOFÚKQ_FILTER_READÚKQ_FILTER_WRITEc                   @   s    e Zd ZdZedƒZedƒZdS )Ú_IKQueuez2
    An interface for KQueue implementations.
    zAn implementation of kqueue(2).zAn implementation of kevent(2).N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   ÚkqueueÚkevent© r   r   ú>/tmp/pip-unpacked-wheel-nrvc_22y/twisted/internet/kqreactor.pyr   *   s   r   c                   @   s€   e Zd ZdZefdd„Zdd„ Zdd„ Zdd	„ Zd
d„ Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ ZeZdS )ÚKQueueReactoram  
    A reactor that uses kqueue(2)/kevent(2) and relies on Python 2.6 or higher
    which has built in support for kqueue in the select module.

    @ivar _kq: A C{kqueue} which will be used to check for I/O readiness.

    @ivar _impl: The implementation of L{_IKQueue} to use.

    @ivar _selectables: A dictionary mapping integer file descriptors to
        instances of L{FileDescriptor} which have been registered with the
        reactor.  All L{FileDescriptor}s which are currently receiving read or
        write readiness notifications will be present as values in this
        dictionary.

    @ivar _reads: A set containing integer file descriptors.  Values in this
        set will be registered with C{_kq} for read readiness notifications
        which will be dispatched to the corresponding L{FileDescriptor}
        instances in C{_selectables}.

    @ivar _writes: A set containing integer file descriptors.  Values in this
        set will be registered with C{_kq} for write readiness notifications
        which will be dispatched to the corresponding L{FileDescriptor}
        instances in C{_selectables}.
    c                 C   s8   || _ | j  ¡ | _tƒ | _tƒ | _i | _tj 	| ¡ dS )aŽ  
        Initialize kqueue object, file descriptor tracking dictionaries, and
        the base class.

        See:
            - http://docs.python.org/library/select.html
            - www.freebsd.org/cgi/man.cgi?query=kqueue
            - people.freebsd.org/~jlemon/papers/kqueue.pdf

        @param _kqueueImpl: The implementation of L{_IKQueue} to use. A
            hook for testing.
        N)
Ú_implr   Ú_kqÚsetÚ_readsÚ_writesÚ_selectablesr   ÚPosixReactorBaseÚ__init__)ÚselfZ_kqueueImplr   r   r   r"   Q   s    zKQueueReactor.__init__c                 C   s"   | j  | j |||¡gdd¡ dS )z°
        Private method for changing kqueue registration on a given FD
        filtering for events given filter/op. This will never block and
        returns nothing.
        r   N)r   Úcontrolr   r   )r#   ÚfdÚfilterÚopr   r   r   Ú_updateRegistratione   s    z!KQueueReactor._updateRegistrationc                 C   s   | j  ¡  d| _ dS )zA
        Implement L{IReactorDaemonize.beforeDaemonize}.
        N)r   Úclose©r#   r   r   r   ÚbeforeDaemonizem   s    
zKQueueReactor.beforeDaemonizec                 C   sD   | j  ¡ | _| jD ]}|  |tt¡ q| jD ]}|  |tt¡ q,dS )z@
        Implement L{IReactorDaemonize.afterDaemonize}.
        N)	r   r   r   r   r(   r   r   r   r   )r#   r%   r   r   r   ÚafterDaemonize}   s
    

zKQueueReactor.afterDaemonizec              	   C   s\   |  ¡ }|| jkrXz,z|  |tt¡ W n tk
r:   Y nX W 5 || j|< | j |¡ X dS )z7
        Implement L{IReactorFDSet.addReader}.
        N)Úfilenor   r    Úaddr(   r   r   ÚOSError)r#   Úreaderr%   r   r   r   Ú	addReader‹   s    


zKQueueReactor.addReaderc              	   C   s\   |  ¡ }|| jkrXz,z|  |tt¡ W n tk
r:   Y nX W 5 || j|< | j |¡ X dS )z7
        Implement L{IReactorFDSet.addWriter}.
        N)r-   r   r    r.   r(   r   r   r/   )r#   Úwriterr%   r   r   r   Ú	addWriter™   s    


zKQueueReactor.addWriterc                 C   s²   d}z|  ¡ }W n tk
r(   d}Y nX |dkrZ| j ¡ D ]\}}||kr<d} qZq<dS || jkr®| j |¡ || jkr‚| j|= |s®z|  |tt	¡ W n t
k
r¬   Y nX dS )z:
        Implement L{IReactorFDSet.removeReader}.
        FéÿÿÿÿTN)r-   ÚBaseExceptionr    Úitemsr   Úremover   r(   r   r   r/   )r#   r0   ÚwasLostr%   Úfdesr   r   r   ÚremoveReader§   s(    


zKQueueReactor.removeReaderc                 C   s²   d}z|  ¡ }W n tk
r(   d}Y nX |dkrZ| j ¡ D ]\}}||kr<d} qZq<dS || jkr®| j |¡ || jkr‚| j|= |s®z|  |tt	¡ W n t
k
r¬   Y nX dS )z:
        Implement L{IReactorFDSet.removeWriter}.
        Fr4   TN)r-   r5   r    r6   r   r7   r   r(   r   r   r/   )r#   r2   r8   r%   r9   r   r   r   ÚremoveWriterÁ   s(    


zKQueueReactor.removeWriterc                    s,   ˆ   ‡ fdd„ˆ jD ƒ‡ fdd„ˆ jD ƒ¡S )z7
        Implement L{IReactorFDSet.removeAll}.
        c                    s   g | ]}ˆ j | ‘qS r   ©r    ©Ú.0r%   r*   r   r   Ú
<listcomp>à   s     z+KQueueReactor.removeAll.<locals>.<listcomp>c                    s   g | ]}ˆ j | ‘qS r   r<   r=   r*   r   r   r?   á   s     )Z
_removeAllr   r   r*   r   r*   r   Ú	removeAllÛ   s    þzKQueueReactor.removeAllc                    s   ‡ fdd„ˆ j D ƒS )z8
        Implement L{IReactorFDSet.getReaders}.
        c                    s   g | ]}ˆ j | ‘qS r   r<   r=   r*   r   r   r?   è   s     z,KQueueReactor.getReaders.<locals>.<listcomp>)r   r*   r   r*   r   Ú
getReadersä   s    zKQueueReactor.getReadersc                    s   ‡ fdd„ˆ j D ƒS )z8
        Implement L{IReactorFDSet.getWriters}.
        c                    s   g | ]}ˆ j | ‘qS r   r<   r=   r*   r   r   r?   î   s     z,KQueueReactor.getWriters.<locals>.<listcomp>)r   r*   r   r*   r   Ú
getWritersê   s    zKQueueReactor.getWritersc              
   C   s¶   |dkrd}z| j  g t| jƒ|¡}W n: tk
r` } z|jtjkrNW Y ¢
dS ‚ W 5 d}~X Y nX | j}|D ]D}|j}z| j| }W n t	k
rœ   Y qlY qlX t
 |||||¡ qldS )z1
        Poll the kqueue for new events.
        Né   )r   r$   Úlenr    r/   ÚerrnoZEINTRÚ_doWriteOrReadÚidentÚKeyErrorr   ZcallWithLogger)r#   ÚtimeoutÚeventsÚeZ_drdwÚeventr%   Ú
selectabler   r   r   ÚdoKEventð   s     

zKQueueReactor.doKEventc           
      C   sÀ   d}d}|j |j|j|jf\}}}}	|t@ r<|r<|	r<tj}nnzD| ¡ dkrVd}tj	}n(|t
krjd}| ¡ }|tkr~d}| ¡ }W n( tk
r¨   t ¡ }t |d¡ Y nX |r¼|  |||¡ dS )z’
        Private method called when a FD is ready for reading, writing or was
        lost. Do the work and raise errors where necessary.
        NFr4   TzSAn exception was raised from application code while processing a reactor selectable)r&   ÚflagsÚdataÚfflagsr   r   ZCONNECTION_LOSTr-   r   Z_NO_FILEDESCr   ZdoReadr   ZdoWriter5   r
   ZFailurer   ÚerrZ_disconnectSelectable)
r#   rM   r%   rL   ÚwhyZinReadr&   rO   rP   rQ   r   r   r   rF     s6    üþ
zKQueueReactor._doWriteOrReadN)r   r   r   r   Úselectr"   r(   r+   r,   r1   r3   r:   r;   r@   rA   rB   rN   rF   ZdoIterationr   r   r   r   r   6   s   	)r   c                  C   s   t ƒ } ddlm} || ƒ dS )z'
    Install the kqueue() reactor.
    r   )ÚinstallReactorN)r   Ztwisted.internet.mainrU   )ÚprU   r   r   r   Úinstall:  s    rW   ) r   rE   rT   Zzope.interfacer   r   r   r   Ztwisted.internetr   r   Ztwisted.internet.interfacesr   r	   Ztwisted.pythonr
   r   Úgetattrr   r   r   r   r   ÚAttributeErrorrK   ÚImportErrorr   ZdirectlyProvidesr!   r   rW   Ú__all__r   r   r   r   Ú<module>   s,   



	  
