o
    Qœ_°Z  ã                   @   sœ  d Z ddlZddlZddlZddlZddlZddlZddlZddl	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mZmZmZmZmZmZ ejrkddlmZ ddlmZ G dd	„ d	eƒZeeef Z ed
ƒZ!e"ƒ Z#d dd„Z$e %e$¡ G dd„ deƒZ&G dd„ de&ƒZ'G dd„ de&ƒZ(dej)dej)fdd„Z*dej)dej)fdd„Z+e	j,dkr¸e-edƒr¸ej.Z/nej0Z/G dd„ de/ƒZ1G dd„ dej2ƒZ3dS )!ak  Bridges between the `asyncio` module and Tornado IOLoop.

.. versionadded:: 3.2

This module integrates Tornado with the ``asyncio`` module introduced
in Python 3.4. This makes it possible to combine the two libraries on
the same event loop.

.. deprecated:: 5.0

   While the code in this module is still used, it is now enabled
   automatically when `asyncio` is available, so applications should
   no longer need to refer to this module directly.

.. note::

   Tornado is designed to use a selector-based event loop. On Windows,
   where a proactor-based event loop has been the default since Python 3.8,
   a selector event loop is emulated by running ``select`` on a separate thread.
   Configuring ``asyncio`` to use a selector event loop may improve performance
   of Tornado (but may reduce performance of other ``asyncio``-based libraries
   in the same process).
é    N©Úconvert_yielded)ÚIOLoopÚ_Selectable)	ÚAnyÚTypeVarÚ	AwaitableÚCallableÚUnionÚOptionalÚListÚTupleÚDict)ÚSet)ÚProtocolc                   @   s   e Zd Zdefdd„ZdS )Ú
_HasFilenoÚreturnc                 C   ó   d S ©N© ©Úselfr   r   ú:/usr/lib/python3/dist-packages/tornado/platform/asyncio.pyÚfileno-   s   z_HasFileno.filenoN)Ú__name__Ú
__module__Ú__qualname__Úintr   r   r   r   r   r   ,   s    r   Ú_Tr   c               	   C   sz   t D ]4} | j� d| _| j ¡  W d   ƒ n1 sw   Y  z| j d¡ W n	 ty0   Y nw | j ¡  qt  	¡  d S )NTó   a)
Ú_selector_loopsÚ_select_condÚ_closing_selectorÚnotifyÚ_waker_wÚsendÚBlockingIOErrorÚ_threadÚjoinÚclear)Úloopr   r   r   Ú_atexit_callback9   s   þÿr+   c                
       st  e Zd Zdejdeddf‡ fdd„Zd.deddfd	d
„Zde	e
ef ded de
ddfdd„Zde	e
ef de
ddfdd„Zde	e
ef ddfdd„Zde
de
ddfdd„Zd/dd„Zd/dd„Zdeded dededef
dd„Zd eddfd!d"„Zdedededdfd#d$„Zdedededdfd%d&„Zd'eejj d(ed)ef dedee fd*d+„Zd'ejjddfd,d-„Z ‡  Z!S )0ÚBaseAsyncIOLoopÚasyncio_loopÚkwargsr   Nc                    s¦   |ˆ _ |ˆ _ttdƒrt|tjƒrt|ƒˆ _i ˆ _tƒ ˆ _	tƒ ˆ _
dˆ _ttjƒD ]
}| ¡ r3tj|= q)ˆ tj|< dˆ _tƒ jdi |¤Ž d‡ fdd„}ˆ  |¡ d S )	NÚProactorEventLoopFr   r   c                      s   t  ¡ ˆ _d S r   )Ú	threadingÚ	get_identÚ_thread_identityr   r   r   r   Úassign_thread_identityx   ó   z:BaseAsyncIOLoop.initialize.<locals>.assign_thread_identityr   ©r   N)r-   Úselector_loopÚhasattrÚasyncioÚ
isinstancer/   ÚAddThreadSelectorEventLoopÚhandlersÚsetÚreadersÚwritersÚclosingÚlistr   Ú_ioloop_for_asyncioÚ	is_closedr2   ÚsuperÚ
initializeÚadd_callback)r   r-   r.   r*   r3   ©Ú	__class__r   r   rD   N   s&   ÿ
€
zBaseAsyncIOLoop.initializeFÚall_fdsc                 C   sj   d| _ t| jƒD ]}| j| \}}|  |¡ |r|  |¡ qtj| j= | j| jur.| j 	¡  | j 	¡  d S ©NT)
r?   r@   r;   Úremove_handlerÚclose_fdr   rA   r-   r6   Úclose)r   rH   ÚfdÚfileobjÚhandler_funcr   r   r   rL   }   s   

€

zBaseAsyncIOLoop.closerM   Úhandler©.NÚeventsc                 C   s’   |   |¡\}}|| jv rtd| ƒ‚||f| j|< |tj@ r/| j || j|tj¡ | j 	|¡ |tj
@ rG| j || j|tj
¡ | j 	|¡ d S d S )Nzfd %s added twice)Úsplit_fdr;   Ú
ValueErrorr   ÚREADr6   Ú
add_readerÚ_handle_eventsr=   ÚaddÚWRITEÚ
add_writerr>   )r   rM   rP   rR   rN   r   r   r   Úadd_handlerŽ   s   


þzBaseAsyncIOLoop.add_handlerc                 C   sÐ   |   |¡\}}|tj@ r#|| jvr"| j || j|tj¡ | j |¡ n|| jv r4| j |¡ | j 	|¡ |tj
@ rS|| jvrQ| j || j|tj
¡ | j |¡ d S d S || jv rf| j |¡ | j 	|¡ d S d S r   )rS   r   rU   r=   r6   rV   rW   rX   Úremove_readerÚremoverY   r>   rZ   Úremove_writer)r   rM   rR   rN   r   r   r   Úupdate_handlerœ   s$   

€


þ
þzBaseAsyncIOLoop.update_handlerc                 C   sl   |   |¡\}}|| jvrd S || jv r| j |¡ | j |¡ || jv r0| j |¡ | j |¡ | j|= d S r   )rS   r;   r=   r6   r\   r]   r>   r^   )r   rM   rN   r   r   r   rJ   ¯   s   


zBaseAsyncIOLoop.remove_handlerc                 C   s   | j | \}}|||ƒ d S r   )r;   )r   rM   rR   rN   rO   r   r   r   rW   »   s   zBaseAsyncIOLoop._handle_eventsc              	   C   sd   zt  ¡ }W n ttfy   d }Y nw z|  ¡  t  | j¡ | j ¡  W t  |¡ d S t  |¡ w r   )r8   Úget_event_loopÚRuntimeErrorÚAssertionErrorÚ_setup_loggingÚset_event_loopr-   Úrun_forever)r   Úold_loopr   r   r   Ústart¿   s   ÿzBaseAsyncIOLoop.startc                 C   s   | j  ¡  d S r   )r-   Ústopr   r   r   r   rh   Ë   r4   zBaseAsyncIOLoop.stopÚwhenÚcallbackÚargsc                 O   s4   | j  td||  ¡  ƒ| jtj|g|¢R i |¤Ž¡S )Nr   )r-   Ú
call_laterÚmaxÚtimeÚ_run_callbackÚ	functoolsÚpartial)r   ri   rj   rk   r.   r   r   r   Úcall_atÎ   s
   ýzBaseAsyncIOLoop.call_atÚtimeoutc                 C   s   |  ¡  d S r   )Úcancel)r   rs   r   r   r   Úremove_timeoutÚ   ó   zBaseAsyncIOLoop.remove_timeoutc                 O   sn   t  ¡ | jkr| jj}n| jj}z|| jtj|g|¢R i |¤Žƒ W d S  t	y-   Y d S  t
y6   Y d S w r   )r0   r1   r2   r-   Ú	call_soonÚcall_soon_threadsafero   rp   rq   ra   ÚAttributeError)r   rj   rk   r.   rw   r   r   r   rE   Ý   s   
&üzBaseAsyncIOLoop.add_callbackc                 O   s@   z| j  | jtj|g|¢R i |¤Ž¡ W d S  ty   Y d S w r   )r-   rx   ro   rp   rq   ra   )r   rj   rk   r.   r   r   r   Úadd_callback_from_signalñ   s   
ÿÿz(BaseAsyncIOLoop.add_callback_from_signalÚexecutorÚfunc.c                 G   s   | j j||g|¢R Ž S r   )r-   Úrun_in_executor)r   r{   r|   rk   r   r   r   r}   û   s   zBaseAsyncIOLoop.run_in_executorc                 C   s   | j  |¡S r   )r-   Úset_default_executor)r   r{   r   r   r   r~     rv   z$BaseAsyncIOLoop.set_default_executor©Fr5   )"r   r   r   r8   ÚAbstractEventLoopr   rD   ÚboolrL   r
   r   r   r	   r[   r_   rJ   rW   rg   rh   ÚfloatÚobjectrr   ru   rE   rz   r   Ú
concurrentÚfuturesÚExecutorr   r   r}   r~   Ú__classcell__r   r   rF   r   r,   M   sn    ÿÿþ/
ÿÿÿ
þ

ÿÿÿÿ
þÿÿÿ
þ

þ
ýü
ûr,   c                       s4   e Zd ZdZdeddf‡ fdd„Zd	dd„Z‡  ZS )
ÚAsyncIOMainLoopa›  ``AsyncIOMainLoop`` creates an `.IOLoop` that corresponds to the
    current ``asyncio`` event loop (i.e. the one returned by
    ``asyncio.get_event_loop()``).

    .. deprecated:: 5.0

       Now used automatically when appropriate; it is no longer necessary
       to refer to this class directly.

    .. versionchanged:: 5.0

       Closing an `AsyncIOMainLoop` now closes the underlying asyncio loop.
    r.   r   Nc                    s   t ƒ jt ¡ fi |¤Ž d S r   )rC   rD   r8   r`   )r   r.   rF   r   r   rD     s   zAsyncIOMainLoop.initializec                 C   r   r   r   r   r   r   r   Úmake_current  s   zAsyncIOMainLoop.make_currentr5   )r   r   r   Ú__doc__r   rD   r‰   r‡   r   r   rF   r   rˆ     s    rˆ   c                       sV   e Zd ZdZdeddf‡ fdd„Zddeddf‡ fd	d
„Zddd„Zddd„Z	‡  Z
S )ÚAsyncIOLoopa–  ``AsyncIOLoop`` is an `.IOLoop` that runs on an ``asyncio`` event loop.
    This class follows the usual Tornado semantics for creating new
    ``IOLoops``; these loops are not necessarily related to the
    ``asyncio`` default event loop.

    Each ``AsyncIOLoop`` creates a new ``asyncio.EventLoop``; this object
    can be accessed with the ``asyncio_loop`` attribute.

    .. versionchanged:: 5.0

       When an ``AsyncIOLoop`` becomes the current `.IOLoop`, it also sets
       the current `asyncio` event loop.

    .. deprecated:: 5.0

       Now used automatically when appropriate; it is no longer necessary
       to refer to this class directly.
    r.   r   Nc                    sB   d| _ t ¡ }ztƒ j|fi |¤Ž W d S  ty    | ¡  ‚ w ©NF)Ú
is_currentr8   Únew_event_looprC   rD   Ú	ExceptionrL   )r   r.   r*   rF   r   r   rD   3  s   üzAsyncIOLoop.initializeFrH   c                    s    | j r|  ¡  tƒ j|d� d S )N)rH   )r�   Úclear_currentrC   rL   )r   rH   rF   r   r   rL   >  s   zAsyncIOLoop.closec              	   C   sH   | j szt ¡ | _W n ttfy   d | _Y nw d| _ t | j¡ d S rI   )r�   r8   r`   Úold_asynciora   rb   rd   r-   r   r   r   r   r‰   C  s   
ÿzAsyncIOLoop.make_currentc                 C   s    | j rt | j¡ d| _ d S d S rŒ   )r�   r8   rd   r‘   r   r   r   r   Ú_clear_current_hookL  s   
þzAsyncIOLoop._clear_current_hookr   r5   )r   r   r   rŠ   r   rD   r�   rL   r‰   r’   r‡   r   r   rF   r   r‹     s    
	r‹   Úasyncio_futurec                 C   s   | S )zßConvert an `asyncio.Future` to a `tornado.concurrent.Future`.

    .. versionadded:: 4.1

    .. deprecated:: 5.0
       Tornado ``Futures`` have been merged with `asyncio.Future`,
       so this method is now a no-op.
    r   )r“   r   r   r   Úto_tornado_futureR  s   	r”   Útornado_futurec                 C   s   t | ƒS )as  Convert a Tornado yieldable object to an `asyncio.Future`.

    .. versionadded:: 4.1

    .. versionchanged:: 4.3
       Now accepts any yieldable object, not just
       `tornado.concurrent.Future`.

    .. deprecated:: 5.0
       Tornado ``Futures`` have been merged with `asyncio.Future`,
       so this method is now equivalent to `tornado.gen.convert_yielded`.
    r   )r•   r   r   r   Úto_asyncio_future^  s   r–   Úwin32ÚWindowsSelectorEventLoopPolicyc                       s(   e Zd ZdZdejf‡ fdd„Z‡  ZS )ÚAnyThreadEventLoopPolicyaD  Event loop policy that allows loop creation on any thread.

    The default `asyncio` event loop policy only automatically creates
    event loops in the main threads. Other threads must create event
    loops explicitly or `asyncio.get_event_loop` (and therefore
    `.IOLoop.current`) will fail. Installing this policy allows event
    loops to be created automatically on any thread, matching the
    behavior of Tornado versions prior to 5.0 (or 5.0 on Python 2).

    Usage::

        asyncio.set_event_loop_policy(AnyThreadEventLoopPolicy())

    .. versionadded:: 5.0

    r   c              	      s:   zt ƒ  ¡ W S  ttfy   |  ¡ }|  |¡ | Y S w r   )rC   r`   ra   rb   rŽ   rd   )r   r*   rF   r   r   r`   ˆ  s   
úz'AnyThreadEventLoopPolicy.get_event_loop)r   r   r   rŠ   r8   r€   r`   r‡   r   r   rF   r   r™   v  s    r™   c                       s  e Zd ZdZh d£Zdedef‡ fdd„Zdej	ddfd	d
„Z
d+dd„Zd+dd„Zd+dd„Zd+dd„Zd+dd„Zd+dd„Zded ded ddfdd„Zdddedef ddfdd„Zddd ed! d"eddfd#d$„Zddd ed! d"eddfd%d&„Zd,d'd(„Zd,d)d*„Z‡  ZS )-r:   a£  Wrap an event loop to add implementations of the ``add_reader`` method family.

    Instances of this class start a second thread to run a selector.
    This thread is completely hidden from the user; all callbacks are
    run on the wrapped event loop's thread.

    This class is used automatically by Tornado; applications should not need
    to refer to it directly.

    It is safe to wrap any event loop with this class, although it only makes sense
    for event loops that do not implement the ``add_reader`` family of methods
    themselves (i.e. ``WindowsProactorEventLoop``)

    Closing the ``AddThreadSelectorEventLoop`` also closes the wrapped event loop.

    >   rL   r'   Ú_readersÚ_waker_rr$   Ú_writersÚ
_real_looprV   rZ   Ú_run_selectÚ_select_argsr!   Ú_handle_eventÚ_start_selectr\   r^   Ú_consume_wakerÚ_handle_selectÚ_wake_selectorr"   Únamer   c                    s"   |t jv rtƒ  |¡S t| j|ƒS r   )r:   ÚMY_ATTRIBUTESrC   Ú__getattribute__Úgetattrr�   )r   r¥   rF   r   r   r§   ¿  s   
z+AddThreadSelectorEventLoop.__getattribute__Ú	real_loopNc                 C   sš   || _ t ¡ | _d | _d| _tjdd| jd�| _| j 	¡  | j  
| j¡ i | _i | _t ¡ \| _| _| j d¡ | j d¡ t | ¡ |  | j| j¡ d S )NFzTornado selectorT)r¥   ÚdaemonÚtarget)r�   r0   Ú	Conditionr!   rŸ   r"   ÚThreadrž   r'   rg   rw   r¡   rš   rœ   ÚsocketÚ
socketpairr›   r$   Úsetblockingr    rX   rV   r¢   )r   r©   r   r   r   Ú__init__Ä  s"   
ÿÿ

z#AddThreadSelectorEventLoop.__init__c                 C   s"   t  | ¡ | j ¡  | j ¡  d S r   )r    Údiscardr›   rL   r$   r   r   r   r   Ú__del__ã  s   

z"AddThreadSelectorEventLoop.__del__c                 C   st   | j � d| _| j  ¡  W d   ƒ n1 sw   Y  |  ¡  | j ¡  t | ¡ | j 	¡  | j
 	¡  | j 	¡  d S rI   )r!   r"   r#   r¤   r'   r(   r    r²   r›   rL   r$   r�   r   r   r   r   rL   í  s   þ



z AddThreadSelectorEventLoop.closec                 C   ó(   z	| j  d¡ W d S  ty   Y d S w )Nr   )r$   r%   r&   r   r   r   r   r¤   ø  ó
   ÿz)AddThreadSelectorEventLoop._wake_selectorc                 C   r´   )Ni   )r›   Úrecvr&   r   r   r   r   r¢   þ  rµ   z)AddThreadSelectorEventLoop._consume_wakerc                 C   sb   | j �$ | jd u sJ ‚t| j ¡ ƒt| j ¡ ƒf| _| j  ¡  W d   ƒ d S 1 s*w   Y  d S r   )r!   rŸ   r@   rš   Úkeysrœ   r#   r   r   r   r   r¡     s
   "ýz(AddThreadSelectorEventLoop._start_selectc              
   C   s"  	 | j �8 | jd u r| js| j  ¡  | jd u r| jr| jr&	 W d   ƒ d S | jd us-J ‚| j\}}d | _W d   ƒ n1 s?w   Y  zt |||¡\}}}|| }W n2 ty† } z&|jttdtjƒkr{t | j	 
¡ gg g d¡\}}}|rzg }n‚ ‚ W Y d }~nd }~ww | j | j||¡ q)NTÚWSAENOTSOCKr   )r!   rŸ   r"   ÚwaitÚselectÚOSErrorÚerrnor¨   ÚEBADFr›   r   r�   rx   r£   )r   Úto_readÚto_writeÚrsÚwsÚxsÚeÚ_r   r   r   rž     s6   
ÿü
ùü€ñÑz&AddThreadSelectorEventLoop._run_selectrÀ   Ú_FileDescriptorLikerÁ   c                 C   s<   |D ]	}|   || j¡ q|D ]	}|   || j¡ q|  ¡  d S r   )r    rš   rœ   r¡   )r   rÀ   rÁ   ÚrÚwr   r   r   r£   ?  s
   z)AddThreadSelectorEventLoop._handle_selectrM   Úcb_mapc                 C   s,   z|| }W n
 t y   Y d S w |ƒ  d S r   )ÚKeyError)r   rM   rÈ   rj   r   r   r   r    H  s   ÿ
z(AddThreadSelectorEventLoop._handle_eventrj   rQ   rk   c                 G   ó$   t j|g|¢R Ž | j|< |  ¡  d S r   )rp   rq   rš   r¤   ©r   rM   rj   rk   r   r   r   rV   Q  ó   z%AddThreadSelectorEventLoop.add_readerc                 G   rÊ   r   )rp   rq   rœ   r¤   rË   r   r   r   rZ   W  rÌ   z%AddThreadSelectorEventLoop.add_writerc                 C   ó   | j |= |  ¡  d S r   )rš   r¤   ©r   rM   r   r   r   r\   ]  ó   z(AddThreadSelectorEventLoop.remove_readerc                 C   rÍ   r   )rœ   r¤   rÎ   r   r   r   r^   a  rÏ   z(AddThreadSelectorEventLoop.remove_writerr5   )rM   rÅ   r   N)r   r   r   rŠ   r¦   Ústrr   r§   r8   r€   r±   r³   rL   r¤   r¢   r¡   rž   r   r£   r   r	   r    rV   rZ   r\   r^   r‡   r   r   rF   r   r:   ”  sZ    






	2ÿÿ
þ	ÿ
ÿ
þ	ÿÿÿ
þÿÿÿ
þ
r:   r5   )4rŠ   r8   ÚatexitÚconcurrent.futuresr„   r¼   rp   rº   r®   Úsysr0   ÚtypingÚtornado.genr   Útornado.ioloopr   r   r   r   r   r	   r
   r   r   r   r   ÚTYPE_CHECKINGr   Útyping_extensionsr   r   r   rÅ   r   r<   r    r+   Úregisterr,   rˆ   r‹   ÚFuturer”   r–   Úplatformr7   r˜   Ú_BasePolicyÚDefaultEventLoopPolicyr™   r€   r:   r   r   r   r   Ú<module>   sD    ,

 ;3