U
    ¹êW[4(  ã                   @   sÜ   d Z ddlmZmZ ddlZddlZddlmZmZ ddlmZm	Z	m
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 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()
é    )ÚdivisionÚabsolute_importN)ÚKQ_FILTER_READÚKQ_FILTER_WRITE)ÚKQ_EV_DELETEÚ	KQ_EV_ADDÚ	KQ_EV_EOF)ÚimplementerÚdeclarationsÚ	InterfaceÚ	Attribute)ÚmainÚ	posixbase)ÚIReactorFDSetÚIReactorDaemonize)ÚlogÚfailurec                   @   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   ú</usr/lib/python3/dist-packages/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$   I   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   Ú_updateRegistration^   s    z!KQueueReactor._updateRegistrationc                 C   s   | j  ¡  d| _ dS )zA
        Implement L{IReactorDaemonize.beforeDaemonize}.
        N)r   Úclose©r%   r   r   r   ÚbeforeDaemonizeg   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   ÚafterDaemonizex   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"   r0   r*   r   r   r1   )r%   Úwriterr'   r   r   r   Ú	addWriter–   s    


zKQueueReactor.addWriterc                 C   sª   d}z|  ¡ }W n   d}Y nX |dkrR| j ¡ D ]\}}||kr4d} qRq4dS || jkr¦| j |¡ || jkrz| j|= |s¦z|  |tt¡ W n t	k
r¤   Y nX dS )z:
        Implement L{IReactorFDSet.removeReader}.
        FéÿÿÿÿTN)
r/   r"   Úitemsr    Úremover!   r*   r   r   r1   )r%   r2   ÚwasLostr'   Úfdesr   r   r   ÚremoveReader¥   s(    


zKQueueReactor.removeReaderc                 C   sª   d}z|  ¡ }W n   d}Y nX |dkrR| j ¡ D ]\}}||kr4d} qRq4dS || jkr¦| j |¡ || jkrz| j|= |s¦z|  |tt¡ W n t	k
r¤   Y nX dS )z:
        Implement L{IReactorFDSet.removeWriter}.
        Fr6   TN)
r/   r"   r7   r!   r8   r    r*   r   r   r1   )r%   r4   r9   r'   r:   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"   r1   ÚerrnoZEINTRÚ_doWriteOrReadZidentÚKeyErrorr   ZcallWithLogger)r%   ZtimeoutZ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}nfzD| ¡ dkrVd}tj	}n(|t
krjd}| ¡ }|tkr~d}| ¡ }W n    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.
        NFr6   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doWriter   ZFailurer   ÚerrZ_disconnectSelectable)
r%   rK   r'   rJ   ZwhyZinReadr(   rM   rN   rO   r   r   r   rG     s0       ÿzKQueueReactor._doWriteOrReadN)r   r   r   r   Úselectr$   r*   r-   r.   r3   r5   r;   r<   rA   rB   rC   rL   rG   ZdoIterationr   r   r   r   r   .   s   		"r   c                  C   s   t ƒ } ddlm} || ƒ dS )z'
    Install the kqueue() reactor.
    r   )ÚinstallReactorN)r   Ztwisted.internet.mainrR   )ÚprR   r   r   r   Úinstall7  s    rT   )r   Z
__future__r   r   rF   rQ   r   r   r   r   r   Zzope.interfacer	   r
   r   r   Ztwisted.internetr   r   Ztwisted.internet.interfacesr   r   Ztwisted.pythonr   r   r   ZdirectlyProvidesr#   r   rT   Ú__all__r   r   r   r   Ú<module>   s"     
	