a XC?hL��@s$dZdZddlZddlZddlZddlZddlZddlZddlZz ddl Z Wne ybdZ Yn0ddl m Z ddl m Z ddl mZddl mZdd l mZdd l mZdd l mZdd l mZdd lmZdd�ZGdd�de j�ZGdd�dejej�ZGdd�de�ZGdd�de�ZdS)z�Event loop using a selector and related classes. A selector is a "notify-when-ready" multiplexer. For a subclass which also includes support for signal handling, see the unix_events sub-module. )�BaseSelectorEventLoop�N�)� base_events)� constants)�events)�futures)� protocols)�sslproto)� transports)�trsock)�loggercCs6z|�|�}Wnty"YdS0t|j|@�SdS�NF)�get_key�KeyError�boolr)�selector�fdZevent�key�r��Z!d?d@�Z"dAdB�Z#dCdD�Z$dXdEdF�Z%dGdH�Z&dIdJ�Z'dKdL�Z(dMdN�Z)dOdP�Z*dQdR�Z+�Z,S)YrzJSelector event loop. See events.EventLoop for API specification. NcsFt���|durt��}t�d|jj�||_|� �t � �|_ dS)NzUsing selector: %s) �super�__init__� selectorsZDefaultSelectorr �debug� __class__�__name__� _selector�_make_self_pipe�weakrefZWeakValueDictionary� _transports)�selfr�rrrr1s zBaseSelectorEventLoop.__init__��extra�servercCst||||||�S�N)�_SelectorSocketTransport)r!�sock�protocol�waiterr$r%rrr�_make_socket_transport;s �z,BaseSelectorEventLoop._make_socket_transportF)� server_side�server_hostnamer$r%�ssl_handshake_timeoutc Cs0tj||||||| d�} t||| ||d�| jS)N)r.r#)r Z SSLProtocolr'Z_app_transport) r!Zrawsockr)� sslcontextr*r,r-r$r%r.Z ssl_protocolrrr�_make_ssl_transport@s��z)BaseSelectorEventLoop._make_ssl_transportcCst||||||�Sr&)�_SelectorDatagramTransport)r!r(r)�addressr*r$rrr�_make_datagram_transportMs�z.BaseSelectorEventLoop._make_datagram_transportcsL|��rtd��|��rdS|��t���|jdurH|j��d|_dS)Nz!Cannot close a running event loop)Z is_running� RuntimeError� is_closed�_close_self_piper�closer�r!r"rrr7Rs   zBaseSelectorEventLoop.closecCsB|�|j���|j��d|_|j��d|_|jd8_dS)Nr)�_remove_reader�_ssock�filenor7�_csock� _internal_fdsr8rrrr6]s   z&BaseSelectorEventLoop._close_self_pipecCsNt��\|_|_|j�d�|j�d�|jd7_|�|j��|j�dS)NFr) �socketZ socketpairr:r<� setblockingr=� _add_readerr;�_read_from_selfr8rrrres   z%BaseSelectorEventLoop._make_self_pipecCsdSr&r�r!�datarrr�_process_self_datamsz(BaseSelectorEventLoop._process_self_datacCsTz"|j�d�}|sWqP|�|�Wqty8YqYqtyLYqPYq0qdS)Ni)r:�recvrD�InterruptedError�BlockingIOErrorrBrrrrAps   z%BaseSelectorEventLoop._read_from_selfcCsL|j}|durdSz|�d�Wn&tyF|jrBtjddd�Yn0dS)N�z3Fail to write a null byte into the self-pipe socketT��exc_info)r<�send�OSError�_debugr r)r!Zcsockrrr�_write_to_self|s �z$BaseSelectorEventLoop._write_to_self�dc Cs"|�|��|j||||||�dSr&)r@r;�_accept_connection)r!�protocol_factoryr(r/r%�backlogr.rrr�_start_serving�s �z$BaseSelectorEventLoop._start_servingc Cst|�D]�}z0|��\}} |jr0t�d|| |�|�d�Wn�tttfyXYdSt y�} zl| j t j t j t j t jfvr�|�d| t�|�d��|�|���|�tj|j||||||�n�WYd} ~ qd} ~ 00d| i} |�||| |||�} |�| �qdS)Nz#%r got a new connection from %r: %rFz&socket.accept() out of system resource)�message� exceptionr>�peername)�range�acceptrMr rr?rGrF�ConnectionAbortedErrorrL�errnoZEMFILEZENFILEZENOBUFSZENOMEM�call_exception_handlerr �TransportSocketr9r;Z call_laterrZACCEPT_RETRY_DELAYrS�_accept_connection2Z create_task) r!rQr(r/r%rRr.�_�conn�addr�excr$rXrrrrP�s@  � ��� �z(BaseSelectorEventLoop._accept_connectionc �s�d}d}zr|�}|��} |r8|j|||| d|||d�}n|j||| ||d�}z| IdHWntyv|���Yn0Wntttfy��Yn^ty�} zF|jr�d| d�} |dur�|| d<|dur�|| d<|�| �WYd} ~ n d} ~ 00dS)NT)r*r,r$r%r.)r*r$r%z3Error on transport creation for incoming connection)rTrUr)� transport) � create_futurer0r+� BaseExceptionr7� SystemExit�KeyboardInterruptrMr[) r!rQr_r$r/r%r.r)rbr*ra�contextrrrr]�s@��  �z)BaseSelectorEventLoop._accept_connection2c Cs�|}t|t�sHzt|���}Wn(tttfyFtd|���d�Yn0z|j|}WntyhYn0|��s�t d|�d|����dS)NzInvalid file object: zFile descriptor z is used by transport ) � isinstance�intr;�AttributeError� TypeError� ValueErrorr r� is_closingr4)r!rr;rbrrr�_ensure_fd_no_transport�s   ��z-BaseSelectorEventLoop._ensure_fd_no_transportc Gs�|��t�|||d�}z|j�|�}Wn(tyP|j�|tj|df�Yn>0|j|j }\}}|j� ||tjB||f�|dur�|� �|Sr&) � _check_closedr�Handlerrr�registerr� EVENT_READrC�modify�cancel� r!r�callback�args�handler�mask�reader�writerrrrr@�s  � �z!BaseSelectorEventLoop._add_readercCs�|��r dSz|j�|�}Wnty0YdS0|j|j}\}}|tjM}|sb|j�|�n|j� ||d|f�|dur�|� �dSdSdS)NFT) r5rrrrrCrrr� unregisterrsrt�r!rrryrzr{rrrr9 s  z$BaseSelectorEventLoop._remove_readerc Gs�|��t�|||d�}z|j�|�}Wn(tyP|j�|tjd|f�Yn>0|j|j }\}}|j� ||tjB||f�|dur�|� �|Sr&) rorrprrrrqr� EVENT_WRITErCrsrtrurrr� _add_writer!s  � �z!BaseSelectorEventLoop._add_writercCs�|��r dSz|j�|�}Wnty0YdS0|j|j}\}}|tjM}|sb|j�|�n|j� |||df�|dur�|� �dSdSdS)�Remove a writer callback.FNT) r5rrrrrCrr~r|rsrtr}rrr�_remove_writer1s  z$BaseSelectorEventLoop._remove_writercGs"|�|�|j||g|�R�dS)zAdd a reader callback.N)rnr@�r!rrvrwrrr� add_readerHs z BaseSelectorEventLoop.add_readercCs|�|�|�|�S)zRemove a reader callback.)rnr9�r!rrrr� remove_readerMs z#BaseSelectorEventLoop.remove_readercGs"|�|�|j||g|�R�dS)zAdd a writer callback..N)rnrr�rrr� add_writerRs z BaseSelectorEventLoop.add_writercCs|�|�|�|�S)r�)rnr�r�rrr� remove_writerWs z#BaseSelectorEventLoop.remove_writerc �s�t�|�|jr$|��dkr$td��z |�|�WSttfyFYn0|��}|� �}|� |�|� ||j |||�}|� tj|j||d��|IdHS)z�Receive data from the socket. The return value is a bytes object representing the data received. The maximum amount of data to be received at once is specified by nbytes. r�the socket must be non-blocking�rxN)r�_check_ssl_socketrM� gettimeoutrlrErGrFrcr;rnr@� _sock_recv�add_done_callback� functools�partial�_sock_read_done)r!r(�n�futrrxrrr� sock_recv\s   �zBaseSelectorEventLoop.sock_recvcCs|dus|��s|�|�dSr&)� cancelledr��r!rr�rxrrrr�rsz%BaseSelectorEventLoop._sock_read_donec Cs�|��r dSz|�|�}WnZttfy2YdSttfyH�Yn8tyt}z|�|�WYd}~nd}~00|�|�dSr&) �donerErGrFrerfrd� set_exception� set_result)r!r�r(r�rCrarrrr�vs z BaseSelectorEventLoop._sock_recvc �s�t�|�|jr$|��dkr$td��z |�|�WSttfyFYn0|��}|� �}|� |�|� ||j |||�}|� tj|j||d��|IdHS)z�Receive data from the socket. The received data is written into *buf* (a writable buffer). The return value is the number of bytes written. rr�r�N)rr�rMr�rl� recv_intorGrFrcr;rnr@�_sock_recv_intor�r�r�r�)r!r(�bufr�rrxrrr�sock_recv_into�s   �z$BaseSelectorEventLoop.sock_recv_intoc Cs�|��r dSz|�|�}WnZttfy2YdSttfyH�Yn8tyt}z|�|�WYd}~nd}~00|�|�dSr&) r�r�rGrFrerfrdr�r�)r!r�r(r��nbytesrarrrr��s z%BaseSelectorEventLoop._sock_recv_intoc �s�t�|�|jr$|��dkr$td��z|�|�}WnttfyLd}Yn0|t|�kr^dS|� �}|� �}|� |�|� ||j ||t|�|g�}|�tj|j||d��|IdHS)a�Send data to the socket. The socket must be connected to a remote socket. This method continues to send data from data until either all data has been sent or an error occurs. None is returned on success. On error, an exception is raised, and there is no way to determine how much data, if any, was successfully processed by the receiving end of the connection. rr�Nr�)rr�rMr�rlrKrGrF�lenrcr;rnr� _sock_sendall� memoryviewr�r�r��_sock_write_done)r!r(rCr�r�rrxrrr� sock_sendall�s&     ��z"BaseSelectorEventLoop.sock_sendallc Cs�|��r dS|d}z|�||d��}Wn\ttfyBYdSttfyX�Yn0ty�}z|�|�WYd}~dSd}~00||7}|t|�kr�|� d�n||d<dS)Nr) r�rKrGrFrerfrdr�r�r�)r!r�r(Zview�pos�startr�rarrrr��s    z#BaseSelectorEventLoop._sock_sendallc�s�t�|�|jr$|��dkr$td��|jtjksBtjrt|jtj krt|j ||j|j |j |d�IdH}|d\}}}}}|� �}|�|||�|IdHS)zTConnect to a remote socket at address. This method is a coroutine. rr�)�family�type�proto�loopN)rr�rMr�rlr�r>ZAF_INETZ _HAS_IPv6ZAF_INET6Z_ensure_resolvedr�r�rc� _sock_connect)r!r(r2Zresolvedr^r�rrr� sock_connect�s   � �� z"BaseSelectorEventLoop.sock_connectc Cs�|��}z|�|�Wn�ttfyb|�|�|�||j|||�}|�tj |j ||d��YnNt t fyx�Yn8t y�}z|�|�WYd}~nd}~00|�d�dS)Nr�)r;ZconnectrGrFrnr�_sock_connect_cbr�r�r�r�rerfrdr�r�)r!r�r(r2rrxrarrrr��s   �� z#BaseSelectorEventLoop._sock_connectcCs|dus|��s|�|�dSr&)r�r�r�rrrr� sz&BaseSelectorEventLoop._sock_write_donec Cs�|��r dSz,|�tjtj�}|dkr6t|d|����WnXttfyNYnNtt fyd�Yn8t y�}z|� |�WYd}~nd}~00|� d�dS)NrzConnect call failed ) r�Z getsockoptr>Z SOL_SOCKETZSO_ERRORrLrGrFrerfrdr�r�)r!r�r(r2�errrarrrr�s z&BaseSelectorEventLoop._sock_connect_cbc�sBt�|�|jr$|��dkr$td��|��}|�||�|IdHS)aWAccept a connection. The socket must be bound to an address and listening for connections. The return value is a pair (conn, address) where conn is a new socket object usable to send and receive data on the connection, and address is the address bound to the socket on the other end of the connection. rr�N)rr�rMr�rlrc� _sock_accept)r!r(r�rrr� sock_accept"s   z!BaseSelectorEventLoop.sock_acceptc Cs�|��}z|��\}}|�d�Wn�ttfyl|�|�|�||j||�}|�t j |j ||d��YnRt t fy��Yn<ty�}z|�|�WYd}~nd}~00|�||f�dS)NFr�)r;rXr?rGrFrnr@r�r�r�r�r�rerfrdr�r�)r!r�r(rr_r2rxrarrrr�1s  � z"BaseSelectorEventLoop._sock_acceptc �s�|j|j=|��}|��|��IdHzL|j|j|||dd�IdHW|��|rZ|��||j|j<S||j|j<n"|��|r�|��||j|j<0dS)NF)Zfallback) r �_sock_fd� is_reading� pause_reading�_make_empty_waiterZ sock_sendfile�_sock�_reset_empty_waiter�resume_reading)r!Ztransp�file�offset�countr�rrr�_sendfile_nativeBs* �  ��z&BaseSelectorEventLoop._sendfile_nativecCs�|D]v\}}|j|j}\}}|tj@rL|durL|jrB|�|�n |�|�|tj@r|dur|jrp|�|�q|�|�qdSr&) �fileobjrCrrrZ _cancelledr9Z _add_callbackr~r�)r!Z event_listrryr�rzr{rrr�_process_eventsPs    z%BaseSelectorEventLoop._process_eventscCs|�|���|��dSr&)r9r;r7)r!r(rrr� _stop_serving^sz#BaseSelectorEventLoop._stop_serving)N)N)N)NNN)N)N)-r� __module__� __qualname__�__doc__rr+rZSSL_HANDSHAKE_TIMEOUTr0r3r7r6rrDrArNrSrPr]rnr@r9rr�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�� __classcell__rrr"rr+sj � �� �   � � .� )  rcs�eZdZdZeZdZd�fdd� Zdd�Zdd�Z d d �Z d d �Z d d�Z dd�Z ejfdd�Zddd�Zdd�Zdd�Zdd�Zdd�Z�ZS) �_SelectorTransportiNcs�t��||�t�|�|jd<z|��|jd<WntyLd|jd<Yn0d|jvr�z|��|jd<Wntj y�d|jd<Yn0||_ |� �|_ d|_ |�|�||_|��|_d|_d|_|jdur�|j��||j|j <dS)Nr>ZsocknamerVFr)rrr r\�_extraZ getsocknamerLZ getpeernamer>�errorr�r;r��_protocol_connected� set_protocol�_server�_buffer_factory�_buffer� _conn_lost�_closingZ_attachr )r!r�r(r)r$r%r"rrros,       z_SelectorTransport.__init__cCs�|jjg}|jdur |�d�n|jr0|�d�|�d|j���|jdur�|j��s�t|jj |jt j �}|rz|�d�n |�d�t|jj |jt j �}|r�d}nd}|� �}|�d|�d |�d ��d �d �|��S) N�closed�closingzfd=z read=pollingz read=idle�pollingZidlezwrite=z<{}>� )rrr��appendr�r��_loopr5rrrrrr~�get_write_buffer_size�format�join)r!�infor��state�bufsizerrr�__repr__�s.    �  �z_SelectorTransport.__repr__cCs|�d�dSr&)� _force_closer8rrr�abort�sz_SelectorTransport.abortcCs||_d|_dS�NT)� _protocolr��r!r)rrrr��sz_SelectorTransport.set_protocolcCs|jSr&)r�r8rrr� get_protocol�sz_SelectorTransport.get_protocolcCs|jSr&)r�r8rrrrm�sz_SelectorTransport.is_closingcCsT|jr dSd|_|j�|j�|jsP|jd7_|j�|j�|j�|jd�dS�NTr) r�r�r9r�r�r�r�� call_soon�_call_connection_lostr8rrrr7�sz_SelectorTransport.closecCs,|jdur(|d|��t|d�|j��dS)Nzunclosed transport )�source)r��ResourceWarningr7)r!Z_warnrrr�__del__�s z_SelectorTransport.__del__�Fatal error on transportcCsNt|t�r(|j��r@tjd||dd�n|j�||||jd��|�|�dS)Nz%r: %sTrI)rTrUrbr)) rhrLr�� get_debugr rr[r�r�)r!rarTrrr� _fatal_error�s  �z_SelectorTransport._fatal_errorcCsd|jr dS|jr(|j��|j�|j�|jsBd|_|j�|j�|jd7_|j�|j |�dSr�) r�r��clearr�r�r�r�r9r�r��r!rarrrr��s z_SelectorTransport._force_closecCs�zN|jr|j�|�W|j��d|_d|_d|_|j}|dur�|��d|_n:|j��d|_d|_d|_|j}|dur�|��d|_0dSr&)r�r�Zconnection_lostr�r7r�r�Z_detach)r!rar%rrrr��s& � z(_SelectorTransport._call_connection_lostcCs t|j�Sr&)r�r�r8rrrr��sz(_SelectorTransport.get_write_buffer_sizecGs$|jr dS|jj||g|�R�dSr&)r�r�r@r�rrrr@�sz_SelectorTransport._add_reader)NN)r�)rr�r��max_size� bytearrayr�r�rr�r�r�r�rmr7�warnings�warnr�r�r�r�r�r@r�rrr"rr�cs    r�cs�eZdZdZejjZd#�fdd� Z�fdd�Z dd�Z d d �Z d d �Z d d�Z dd�Zdd�Zdd�Zdd�Zdd�Zdd�Zdd�Z�fdd�Zdd �Zd!d"�Z�ZS)$r'TNcs~d|_t��|||||�d|_d|_d|_t�|j�|j � |j j |�|j � |j |j|j�|durz|j � tj|d�dSr )�_read_ready_cbrr�_eof�_paused� _empty_waiterrZ _set_nodelayr�r�r�r��connection_mader@r�� _read_readyr�_set_result_unless_cancelled)r!r�r(r)r*r$r%r"rrr�s  � �z!_SelectorSocketTransport.__init__cs.t|tj�r|j|_n|j|_t��|�dSr&)rhrZBufferedProtocol�_read_ready__get_bufferr��_read_ready__data_receivedrr�r�r"rrr�s  z%_SelectorSocketTransport.set_protocolcCs|j o|j Sr&)r�r�r8rrrr�sz#_SelectorSocketTransport.is_readingcCs>|js |jrdSd|_|j�|j�|j��r:t�d|�dS)NTz%r pauses reading)r�r�r�r9r�r�r rr8rrrr�s   z&_SelectorSocketTransport.pause_readingcCs@|js |jsdSd|_|�|j|j�|j��r�      z_SelectorSocketTransport.writec Cs|jr dSz|j�|j�}Wn�ttfy2Yn�ttfyH�Yn�ty�}zF|j � |j �|j� �|� |d�|jdur�|j�|�WYd}~nvd}~00|r�|jd|�=|��|j�s|j � |j �|jdur�|j�d�|jr�|�d�n|j�r|j�tj�dS)Nr�)r�r�rKr�rGrFrerfrdr�r�r�r�r�r�r��_maybe_resume_protocolr�r�r�r��shutdownr>�SHUT_WR)r!r�rarrrr�s2   "    z%_SelectorSocketTransport._write_readycCs.|js |jrdSd|_|js*|j�tj�dSr�)r�r�r�r�rr>rr8rrr� write_eof�s  z"_SelectorSocketTransport.write_eofcCsdSr�rr8rrr� can_write_eof�sz&_SelectorSocketTransport.can_write_eofcs*t��|�|jdur&|j�td��dS)NzConnection is closed by peer)rr�r�r��ConnectionErrorr�r"rrr��s   �z._SelectorSocketTransport._call_connection_lostcCs6|jdurtd��|j��|_|js0|j�d�|jS)NzEmpty waiter is already set)r�r4r�rcr�r�r8rrrr��s    z+_SelectorSocketTransport._make_empty_waitercCs d|_dSr&)r�r8rrrr��sz,_SelectorSocketTransport._reset_empty_waiter)NNN)rr�r�Z_start_tls_compatiblerZ _SendfileModeZ TRY_NATIVEZ_sendfile_compatiblerr�r�r�r�r�r�r�r�rrrrr�r�r�r�rrr"rr'�s(� %' r'csFeZdZejZd �fdd� Zdd�Zdd�Zd dd �Z d d �Z �Z S)r1Ncs^t��||||�||_|j�|jj|�|j�|j|j|j �|durZ|j�t j |d�dSr&) rr�_addressr�r�r�r�r@r�r�rr�)r!r�r(r)r2r*r$r"rrr�s � �z#_SelectorDatagramTransport.__init__cCstdd�|jD��S)Ncss|]\}}t|�VqdSr&)r�)�.0rCr^rrr� ��zC_SelectorDatagramTransport.get_write_buffer_size..)�sumr�r8rrrr��sz0_SelectorDatagramTransport.get_write_buffer_sizec Cs�|jr dSz|j�|j�\}}Wn�ttfy6Yn�tyd}z|j�|�WYd}~n\d}~0t t fyz�Yn>t y�}z|� |d�WYd}~nd}~00|j� ||�dS)Nz&Fatal read error on datagram transport)r�r�Zrecvfromr�rGrFrLr��error_receivedrerfrdr�Zdatagram_received�r!rCr`rarrrr��s "z&_SelectorDatagramTransport._read_readyc Cs�t|tttf�s$tdt|�j����|s,dS|jrV|d|jfvrPtd|j����|j}|j r�|jr�|j t j krxt � d�|j d7_ dS|j�sdz,|jdr�|j�|�n|j�||�WdSttfy�|j�|j|j�Yn~t�y}z|j�|�WYd}~dSd}~0ttf�y0�Yn4t�yb}z|�|d�WYd}~dSd}~00|j� t|�|f�|�!�dS)Nr�z!Invalid address: must be None or r�rrV�'Fatal write error on datagram transport)"rhr�r�r�rkr�rr rlr�rr�r r�r�r�r�rK�sendtorGrFr�rr�� _sendto_readyrLr�rrerfrdr�r�rrrrrrsJ� �     �z!_SelectorDatagramTransport.sendtoc Cs|jr�|j��\}}z*|jdr.|j�|�n|j�||�Wqttfyh|j�||f�Yq�Yqt y�}z|j � |�WYd}~dSd}~0t t fy��Yqty�}z|�|d�WYd}~dSd}~00q|��|j�s|j�|j�|j�r|�d�dS)NrVr)r��popleftr�r�rKrrGrF� appendleftrLr�rrerfrdr�rr�r�r�r�r�rrrrr0s0  �z(_SelectorDatagramTransport._sendto_ready)NNN)N) rr�r�� collections�dequer�rr�r�rrr�rrr"rr1�s�  +r1)r��__all__rrZr�rr>r�rZssl� ImportError�rrrrrr r r �logr rZ BaseEventLooprZ_FlowControlMixinZ Transportr�r'r1rrrr�sD             <�o