ó
    Rì?gÒ�  ã                   ó–  • S r SSKrSSKrSSKrSSKrSSKrSSKrSSKrSSK	r	SSK
r
SSKrSSKrSSKJr  SSKJrJrJrJrJr  SSKJr  SSKJrJrJr  SSKrSSKJrJrJrJrJ r J!r!J"r"J#r#  \RH                  (       a  SSKJ%r%J&r&J'r'  SS	K(J)r)  O\*r) " S
 S\)5      r+\!" S5      r,\!" S\+S9r- " S S\5      r. " S S\*5      r/ " S S\*5      r0g)a©  An I/O event loop for non-blocking sockets.

In Tornado 6.0, `.IOLoop` is a wrapper around the `asyncio` event loop, with a
slightly different interface. The `.IOLoop` interface is now provided primarily
for backwards compatibility; new code should generally use the `asyncio` event
loop interface directly. The `IOLoop.current` class method provides the
`IOLoop` instance corresponding to the running `asyncio` event loop.

é    N)Úisawaitable)ÚFutureÚ	is_futureÚchain_futureÚfuture_set_exc_infoÚfuture_add_done_callback)Úapp_log)ÚConfigurableÚTimeoutErrorÚimport_object)ÚUnionÚAnyÚTypeÚOptionalÚCallableÚTypeVarÚTupleÚ	Awaitable)ÚDictÚListÚSet)ÚProtocolc                   ó,   • \ rS rSrS\4S jrSS jrSrg)Ú_Selectableé<   Úreturnc                 ó   • g ©N© ©Úselfs    Ú0/usr/lib/python3/dist-packages/tornado/ioloop.pyÚfilenoÚ_Selectable.fileno=   ó   € Øó    Nc                 ó   • g r   r   r    s    r"   ÚcloseÚ_Selectable.close@   r%   r&   r   ©r   N)Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Úintr#   r(   Ú__static_attributes__r   r&   r"   r   r   <   s   † ð˜ô ÷r&   r   Ú_TÚ_S)Úboundc            
       óF  ^ • \ rS rSrSrSrSrSrSr\	" 5       r
\" 5       r\SSS	\S
S4U 4S jj5       r\SJS j5       rSKS jr\SKS j5       r\R*                  \SJS j5       5       r\R*                  \SLS\S
\S    4S jj5       5       r\SLS\S
\S    4S jj5       rSKS jrSKS jr\SKS j5       r\SKS j5       rSKS jr\S
\\   4S j5       r \S
\\   4S j5       r!SLS\S
S4S jjr"SMS\S
S4S jjr#\R*                  S\$S \%\$\$/S4   S!\$S
S4S" j5       r&\R*                  S\'S \%\'\$/S4   S!\$S
S4S# j5       r&S\(\$\)4   S \%S$   S!\$S
S4S% jr&S\(\$\)4   S!\$S
S4S& jr*S\(\$\)4   S
S4S' jr+SKS( jr,SKS) jr-SNS*\%S+\\.   S
\4S, jjr/S
\.4S- jr0S.\(\.\1Rd                  4   S/\%S0\S	\S
\34
S1 jr4S2\.S/\%S0\S	\S
\34
S3 jr5S4\.S/\%S0\S	\S
\34
S5 jr6S+\3S
S4S6 jr7S/\%S0\S	\S
S4S7 jr8S/\%S0\S	\S
S4S8 jr9S/\%S0\S	\S
S4S9 jr:S:S;S/\%S</S4   S
S4S= jr;S>\\<Rz                  R|                     S*\%S?\?4   S0\S
S<4S@ jr@S>\<Rz                  R|                  S
S4SA jrAS/\%/ \4   S
S4SB jrBS:\CS
S4SC jrDS\(\$\)4   S
\E\$\(\$\)4   4   4SD jrFS\(\$\)4   S
S4SE jrGSF\CS
S4SG jrHSF\CS
S4SH jrISIrJU =rK$ )OÚIOLoopéH   a  An I/O event loop.

As of Tornado 6.0, `IOLoop` is a wrapper around the `asyncio` event loop.

Example usage for a simple TCP server:

.. testcode::

    import asyncio
    import errno
    import functools
    import socket

    import tornado
    from tornado.iostream import IOStream

    async def handle_connection(connection, address):
        stream = IOStream(connection)
        message = await stream.read_until_close()
        print("message from client:", message.decode().strip())

    def connection_ready(sock, fd, events):
        while True:
            try:
                connection, address = sock.accept()
            except BlockingIOError:
                return
            connection.setblocking(0)
            io_loop = tornado.ioloop.IOLoop.current()
            io_loop.spawn_callback(handle_connection, connection, address)

    async def main():
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
        sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        sock.setblocking(0)
        sock.bind(("", 8888))
        sock.listen(128)

        io_loop = tornado.ioloop.IOLoop.current()
        callback = functools.partial(connection_ready, sock)
        io_loop.add_handler(sock.fileno(), callback, io_loop.READ)
        await asyncio.Event().wait()

    if __name__ == "__main__":
        asyncio.run(main())

.. testoutput::
   :hide:

Most applications should not attempt to construct an `IOLoop` directly,
and instead initialize the `asyncio` event loop and use `IOLoop.current()`.
In some cases, such as in test frameworks when initializing an `IOLoop`
to be run in a secondary thread, it may be appropriate to construct
an `IOLoop` with ``IOLoop(make_current=False)``.

In general, an `IOLoop` cannot survive a fork or be shared across processes
in any way. When multiple processes are being used, each process should
create its own `IOLoop`, which also implies that any objects which depend on
the `IOLoop` (such as `.AsyncHTTPClient`) must also be created in the child
processes. As a guideline, anything that starts processes (including the
`tornado.process` and `multiprocessing` modules) should do so as early as
possible, ideally the first thing the application does after loading its
configuration, and *before* any calls to `.IOLoop.start` or `asyncio.run`.

.. versionchanged:: 4.2
   Added the ``make_current`` keyword argument to the `IOLoop`
   constructor.

.. versionchanged:: 5.0

   Uses the `asyncio` event loop by default. The ``IOLoop.configure`` method
   cannot be used on Python 3 except to redundantly specify the `asyncio`
   event loop.

.. versionchanged:: 6.3
   ``make_current=True`` is now the default when creating an IOLoop -
   previously the default was to make the event loop current if there wasn't
   already a current one.
r   é   é   é   Úimplz$Union[None, str, Type[Configurable]]Úkwargsr   Nc                 óÜ   >• SSK Jn  [        U[        5      (       a  [	        U5      n[        U[
        5      (       a  [        X5      (       d  [        S5      e[        [        U ]*  " U40 UD6  g )Nr   )ÚBaseAsyncIOLoopz5only AsyncIOLoop is allowed when asyncio is available)Útornado.platform.asyncior=   Ú
isinstanceÚstrr   ÚtypeÚ
issubclassÚRuntimeErrorÚsuperr5   Ú	configure)Úclsr:   r;   r=   Ú	__class__s       €r"   rE   ÚIOLoop.configure®   sV   ø€ õ 	=ä�dœC× Ñ Ü  Ó&ˆDÜ�dœD×!Ñ!¬*°T×*KÑ*KÜÐVÓWÐWÜŒf�cÒ$ TÑ4¨VÓ4r&   c                  ó*   • [         R                  5       $ )aÛ  Deprecated alias for `IOLoop.current()`.

.. versionchanged:: 5.0

   Previously, this method returned a global singleton
   `IOLoop`, in contrast with the per-thread `IOLoop` returned
   by `current()`. In nearly all cases the two were the same
   (when they differed, it was generally used from non-Tornado
   threads to communicate back to the main thread's `IOLoop`).
   This distinction is not present in `asyncio`, so in order
   to facilitate integration with that package `instance()`
   was changed to be an alias to `current()`. Applications
   using the cross-thread communications aspect of
   `instance()` should instead set their own global variable
   to point to the `IOLoop` they want to use.

.. deprecated:: 5.0
)r5   Úcurrentr   r&   r"   ÚinstanceÚIOLoop.instanceº   s   € ô( �~‰~ÓÐr&   c                 ó$   • U R                  5         g)a(  Deprecated alias for `make_current()`.

.. versionchanged:: 5.0

   Previously, this method would set this `IOLoop` as the
   global singleton used by `IOLoop.instance()`. Now that
   `instance()` is an alias for `current()`, `install()`
   is an alias for `make_current()`.

.. deprecated:: 5.0
N)Úmake_currentr    s    r"   ÚinstallÚIOLoop.installÐ   s   € ð 	×ÑÕr&   c                  ó,   • [         R                  5         g)a3  Deprecated alias for `clear_current()`.

.. versionchanged:: 5.0

   Previously, this method would clear the `IOLoop` used as
   the global singleton by `IOLoop.instance()`. Now that
   `instance()` is an alias for `current()`,
   `clear_instance()` is an alias for `clear_current()`.

.. deprecated:: 5.0

N)r5   Úclear_currentr   r&   r"   Úclear_instanceÚIOLoop.clear_instanceÞ   s   € ô 	×ÑÕr&   c                  ó   • g r   r   r   r&   r"   rJ   ÚIOLoop.currentî   ó   € ð 	r&   rK   c                 ó   • g r   r   ©rK   s    r"   rJ   rV   ó   rW   r&   c                 ó2  •  [         R                  " 5       n [
        R                  U   $ ! [         a7    U (       d   g[         R                  " 5       n[         R                  " U5         NTf = f! [         a    U (       a  SSKJ	n  U" 5       n U$ Sn U$ f = f)a«  Returns the current thread's `IOLoop`.

If an `IOLoop` is currently running or has been marked as
current by `make_current`, returns that instance.  If there is
no current `IOLoop` and ``instance`` is true, creates one.

.. versionchanged:: 4.1
   Added ``instance`` argument to control the fallback to
   `IOLoop.instance()`.
.. versionchanged:: 5.0
   On Python 3, control of the current `IOLoop` is delegated
   to `asyncio`, with this and other methods as pass-through accessors.
   The ``instance`` argument now controls whether an `IOLoop`
   is created automatically when there is none, instead of
   whether we fall back to `IOLoop.instance()` (which is now
   an alias for this method). ``instance=False`` is deprecated,
   since even if we do not create an `IOLoop`, this method
   may initialize the asyncio loop.

.. deprecated:: 6.2
   It is deprecated to call ``IOLoop.current()`` when no `asyncio`
   event loop is running.
Nr   )ÚAsyncIOMainLoop)
ÚasyncioÚget_event_looprC   Únew_event_loopÚset_event_loopr5   Ú_ioloop_for_asyncioÚKeyErrorr>   r[   )rK   Úloopr[   rJ   s       r"   rJ   rV   ø   s�   € ð2	)Ü×)Ò)Ó+ˆDð	Ü×-Ñ-¨dÑ3Ð3øô ó 	)ÞÙä×)Ò)Ó+ˆDÜ×"Ò" 4Ö(ð	)ûô ó 	ÞÝDá)Ó+‘ð ˆð ‘Øˆð	ús+   ‚+ ˜A/ «A,¾+A,Á+A,Á/BÂBÂBc                 óX   • [         R                  " S[        SS9  U R                  5         g)aƒ  Makes this the `IOLoop` for the current thread.

An `IOLoop` automatically becomes current for its thread
when it is started, but it is sometimes useful to call
`make_current` explicitly before starting the `IOLoop`,
so that code run at startup time can find the right
instance.

.. versionchanged:: 4.1
   An `IOLoop` created while there is no current `IOLoop`
   will automatically become current.

.. versionchanged:: 5.0
   This method also sets the current `asyncio` event loop.

.. deprecated:: 6.2
   Setting and clearing the current event loop through Tornado is
   deprecated. Use ``asyncio.set_event_loop`` instead if you need this.
z6make_current is deprecated; start the event loop firsté   ©Ú
stacklevelN)ÚwarningsÚwarnÚDeprecationWarningÚ_make_currentr    s    r"   rN   ÚIOLoop.make_current%  s'   € ô( 	�ŠØDÜØò	
ð
 	×ÑÕr&   c                 ó   • [        5       er   ©ÚNotImplementedErrorr    s    r"   rj   ÚIOLoop._make_current@  s   € ä!Ó#Ð#r&   c                  ó`   • [         R                  " S[        SS9  [        R	                  5         g)z×Clears the `IOLoop` for the current thread.

Intended primarily for use by test frameworks in between tests.

.. versionchanged:: 5.0
   This method also clears the current `asyncio` event loop.
.. deprecated:: 6.2
zclear_current is deprecatedrd   re   N)rg   rh   ri   r5   Ú_clear_currentr   r&   r"   rR   ÚIOLoop.clear_currentD  s'   € ô 	�ŠØ)ÜØò	
ô
 	×ÑÕr&   c                  óR   • [         R                  SS9n U b  U R                  5         g g )NFrY   )r5   rJ   Ú_clear_current_hook)Úolds    r"   rq   ÚIOLoop._clear_currentU  s(   € ä�n‰n eˆnÐ,ˆØ‰?Ø×#Ñ#Õ%ð r&   c                 ó   • g)zInstance method called when an IOLoop ceases to be current.

May be overridden by subclasses as a counterpart to make_current.
Nr   r    s    r"   rt   ÚIOLoop._clear_current_hook[  s   € ð
 	r&   c                 ó   • [         $ r   )r5   )rF   s    r"   Úconfigurable_baseÚIOLoop.configurable_baseb  s   € äˆr&   c                 ó   • SSK Jn  U$ )Nr   )ÚAsyncIOLoop)r>   r}   )rF   r}   s     r"   Úconfigurable_defaultÚIOLoop.configurable_defaultf  s   € å8àÐr&   rN   c                 ó4   • U(       a  U R                  5         g g r   )rj   )r!   rN   s     r"   Ú
initializeÚIOLoop.initializel  s   € ÞØ×ÑÕ ð r&   Úall_fdsc                 ó   • [        5       e)a  Closes the `IOLoop`, freeing any resources used.

If ``all_fds`` is true, all file descriptors registered on the
IOLoop will be closed (not just the ones created by the
`IOLoop` itself).

Many applications will only use a single `IOLoop` that runs for the
entire lifetime of the process.  In that case closing the `IOLoop`
is not necessary since everything will be cleaned up when the
process exits.  `IOLoop.close` is provided mainly for scenarios
such as unit tests, which create and destroy a large number of
``IOLoops``.

An `IOLoop` must be completely stopped before it can be closed.  This
means that `IOLoop.stop()` must be called *and* `IOLoop.start()` must
be allowed to return before attempting to call `IOLoop.close()`.
Therefore the call to `close` will usually appear just after
the call to `start` rather than near the call to `stop`.

.. versionchanged:: 3.1
   If the `IOLoop` implementation supports non-integer objects
   for "file descriptors", those objects will have their
   ``close`` method when ``all_fds`` is true.
rm   )r!   rƒ   s     r"   r(   ÚIOLoop.closep  s   € ô2 "Ó#Ð#r&   ÚfdÚhandlerÚeventsc                 ó   • g r   r   ©r!   r†   r‡   rˆ   s       r"   Úadd_handlerÚIOLoop.add_handler‹  ó   € ð 	r&   c                 ó   • g r   r   rŠ   s       r"   r‹   rŒ   ‘  r�   r&   ).Nc                 ó   • [        5       e)aã  Registers the given handler to receive the given events for ``fd``.

The ``fd`` argument may either be an integer file descriptor or
a file-like object with a ``fileno()`` and ``close()`` method.

The ``events`` argument is a bitwise or of the constants
``IOLoop.READ``, ``IOLoop.WRITE``, and ``IOLoop.ERROR``.

When an event occurs, ``handler(fd, events)`` will be run.

.. versionchanged:: 4.0
   Added the ability to pass file-like objects in addition to
   raw file descriptors.
rm   rŠ   s       r"   r‹   rŒ   —  s   € ô" "Ó#Ð#r&   c                 ó   • [        5       e)z™Changes the events we listen for ``fd``.

.. versionchanged:: 4.0
   Added the ability to pass file-like objects in addition to
   raw file descriptors.
rm   )r!   r†   rˆ   s      r"   Úupdate_handlerÚIOLoop.update_handlerª  ó   € ô "Ó#Ð#r&   c                 ó   • [        5       e)z•Stop listening for events on ``fd``.

.. versionchanged:: 4.0
   Added the ability to pass file-like objects in addition to
   raw file descriptors.
rm   ©r!   r†   s     r"   Úremove_handlerÚIOLoop.remove_handler³  r“   r&   c                 ó   • [        5       e)zžStarts the I/O loop.

The loop will run until one of the callbacks calls `stop()`, which
will make the loop stop after the current event iteration completes.
rm   r    s    r"   ÚstartÚIOLoop.start¼  s   € ô "Ó#Ð#r&   c                 ó   • [        5       e)aY  Stop the I/O loop.

If the event loop is not currently running, the next call to `start()`
will return immediately.

Note that even after `stop` has been called, the `IOLoop` is not
completely stopped until `IOLoop.start` has also returned.
Some work that was scheduled before the call to `stop` may still
be run before the `IOLoop` shuts down.
rm   r    s    r"   ÚstopÚIOLoop.stopÄ  s   € ô "Ó#Ð#r&   ÚfuncÚtimeoutc                 óœ  ^ ^^• S/mSUUU 4S jjnT R                  U5        Ub,  SUU 4S jjnT R                  T R                  5       U-   U5      nT R                  5         Ub  T R	                  W5        TS   c   eTS   R                  5       (       d  TS   R                  5       (       d  [        SU-  5      eTS   R                  5       $ )aÿ  Starts the `IOLoop`, runs the given function, and stops the loop.

The function must return either an awaitable object or
``None``. If the function returns an awaitable object, the
`IOLoop` will run until the awaitable is resolved (and
`run_sync()` will return the awaitable's result). If it raises
an exception, the `IOLoop` will stop and the exception will be
re-raised to the caller.

The keyword-only argument ``timeout`` may be used to set
a maximum duration for the function.  If the timeout expires,
a `asyncio.TimeoutError` is raised.

This method is useful to allow asynchronous calls in a
``main()`` function::

    async def main():
        # do stuff...

    if __name__ == '__main__':
        IOLoop.current().run_sync(main)

.. versionchanged:: 4.3
   Returning a non-``None``, non-awaitable value is now an error.

.. versionchanged:: 5.0
   If a timeout occurs, the ``func`` coroutine will be cancelled.

.. versionchanged:: 6.2
   ``tornado.util.TimeoutError`` is now an alias to ``asyncio.TimeoutError``.
Nc                  ód  >•  T" 5       n U b  SSK Jn  U" U 5      n [        U 5      (       a  U TS'   O![        5       nUTS'   UR	                  U 5         TS   c   eTR                  TS   U4S j5        g ! [
         a1    [        5       nUTS'   [        U[        R                  " 5       5         N\f = f)Nr   )Úconvert_yieldedc                 ó$   >• TR                  5       $ r   )rœ   )Úfuturer!   s    €r"   Ú<lambda>Ú.IOLoop.run_sync.<locals>.run.<locals>.<lambda>  s   ø€ ¸4¿9¹9¼;r&   )
Útornado.genr¢   r   r   Ú
set_resultÚ	Exceptionr   ÚsysÚexc_infoÚ
add_future)Úresultr¢   Úfutrž   Úfuture_cellr!   s      €€€r"   ÚrunÚIOLoop.run_sync.<locals>.runó  s¨   ø€ ð+Ù›�ØÑ%Ý;á,¨VÓ4�Fô ˜V×$Ñ$Ø%+�K ’Nä ›(�CØ%(�K ‘NØ—N‘N 6Õ*Ø˜q‘>Ñ-Ð-Ð-Ø�O‰O˜K¨™NÔ,FÕGøô ó 9Ü“h�Ø!$�˜A‘Ü# C¬¯ª«Ö8ð9ús   ƒA4 Á48B/Â.B/c                  óh   >• T S   c   eT S   R                  5       (       d  TR                  5         g g )Nr   )Úcancelrœ   )r¯   r!   s   €€r"   Útimeout_callbackÚ)IOLoop.run_sync.<locals>.timeout_callback  s6   ø€ ð
 # 1‘~Ñ1Ð1Ð1Ø" 1‘~×,Ñ,×.Ñ.Ø—I‘I•Kð /r&   r   z$Operation timed out after %s secondsr*   )	Úadd_callbackÚadd_timeoutÚtimer™   Úremove_timeoutÚ	cancelledÚdoner   r­   )r!   rž   rŸ   r°   r´   Útimeout_handler¯   s   ``    @r"   Úrun_syncÚIOLoop.run_syncÑ  sÏ   ú€ ð@ �fˆ÷	Hñ 	Hð* 	×Ñ˜#ÔØÑ÷ ð  ð "×-Ñ-¨d¯i©i«k¸GÑ.CÐEUÓVˆNØ�
‰
ŒØÑØ×Ñ Ô/Ø˜1‰~Ñ)Ð)Ð)Ø�q‰>×#Ñ#×%Ñ%¨[¸©^×-@Ñ-@×-BÑ-BÜÐEÈÑOÓPÐPØ˜1‰~×$Ñ$Ó&Ð&r&   c                 ó,   • [         R                   " 5       $ )aO  Returns the current time according to the `IOLoop`'s clock.

The return value is a floating-point number relative to an
unspecified time in the past.

Historically, the IOLoop could be customized to use e.g.
`time.monotonic` instead of `time.time`, but this is not
currently supported and so this method is equivalent to
`time.time`.

)r¸   r    s    r"   r¸   ÚIOLoop.time  s   € ô �yŠy‹{Ðr&   ÚdeadlineÚcallbackÚargsc                 ó2  • [        U[        R                  5      (       a  U R                  " X/UQ70 UD6$ [        U[        R
                  5      (       a6  U R                  " U R                  5       UR                  5       -   U/UQ70 UD6$ [        SU-  5      e)a  Runs the ``callback`` at the time ``deadline`` from the I/O loop.

Returns an opaque handle that may be passed to
`remove_timeout` to cancel.

``deadline`` may be a number denoting a time (on the same
scale as `IOLoop.time`, normally `time.time`), or a
`datetime.timedelta` object for a deadline relative to the
current time.  Since Tornado 4.0, `call_later` is a more
convenient alternative for the relative case since it does not
require a timedelta object.

Note that it is not safe to call `add_timeout` from other threads.
Instead, you must use `add_callback` to transfer control to the
`IOLoop`'s thread, and then call `add_timeout` from there.

Subclasses of IOLoop must implement either `add_timeout` or
`call_at`; the default implementations of each will call
the other.  `call_at` is usually easier to implement, but
subclasses that wish to maintain compatibility with Tornado
versions prior to 4.0 must use `add_timeout` instead.

.. versionchanged:: 4.0
   Now passes through ``*args`` and ``**kwargs`` to the callback.
úUnsupported deadline %r)	r?   ÚnumbersÚRealÚcall_atÚdatetimeÚ	timedeltar¸   Útotal_secondsÚ	TypeError)r!   rÁ   rÂ   rÃ   r;   s        r"   r·   ÚIOLoop.add_timeout+  s�   € ô@ �h¤§¡×-Ñ-Ø—<’< ÐD°TÒD¸VÑDÐDÜ˜¤(×"4Ñ"4×5Ñ5Ø—<’<Ø—	‘	“˜h×4Ñ4Ó6Ñ6¸ðØCGòØKQñð ô Ð5¸Ñ@ÓAÐAr&   Údelayc                 óR   • U R                   " U R                  5       U-   U/UQ70 UD6$ )aR  Runs the ``callback`` after ``delay`` seconds have passed.

Returns an opaque handle that may be passed to `remove_timeout`
to cancel.  Note that unlike the `asyncio` method of the same
name, the returned object does not have a ``cancel()`` method.

See `add_timeout` for comments on thread-safety and subclassing.

.. versionadded:: 4.0
)rÈ   r¸   )r!   rÎ   rÂ   rÃ   r;   s        r"   Ú
call_laterÚIOLoop.call_laterT  s*   € ð �|Š|˜DŸI™I›K¨%Ñ/°ÐK¸DÒKÀFÑKÐKr&   Úwhenc                 ó.   • U R                   " X/UQ70 UD6$ )a¦  Runs the ``callback`` at the absolute time designated by ``when``.

``when`` must be a number using the same reference point as
`IOLoop.time`.

Returns an opaque handle that may be passed to `remove_timeout`
to cancel.  Note that unlike the `asyncio` method of the same
name, the returned object does not have a ``cancel()`` method.

See `add_timeout` for comments on thread-safety and subclassing.

.. versionadded:: 4.0
)r·   )r!   rÒ   rÂ   rÃ   r;   s        r"   rÈ   ÚIOLoop.call_atc  s   € ð  ×Ò Ð@°Ò@¸Ñ@Ð@r&   c                 ó   • [        5       e)z£Cancels a pending timeout.

The argument is a handle as returned by `add_timeout`.  It is
safe to call `remove_timeout` even if the callback has already
been run.
rm   )r!   rŸ   s     r"   r¹   ÚIOLoop.remove_timeoutu  r“   r&   c                 ó   • [        5       e)a¡  Calls the given callback on the next I/O loop iteration.

It is safe to call this method from any thread at any time,
except from a signal handler.  Note that this is the **only**
method in `IOLoop` that makes this thread-safety guarantee; all
other interaction with the `IOLoop` must be done from that
`IOLoop`'s thread.  `add_callback()` may be used to transfer
control from other threads to the `IOLoop`'s thread.
rm   ©r!   rÂ   rÃ   r;   s       r"   r¶   ÚIOLoop.add_callback~  s   € ô "Ó#Ð#r&   c                 ó   • [        5       e)aP  Calls the given callback on the next I/O loop iteration.

Intended to be afe for use from a Python signal handler; should not be
used otherwise.

.. deprecated:: 6.4
   Use ``asyncio.AbstractEventLoop.add_signal_handler`` instead.
   This method is suspected to have been broken since Tornado 5.0 and
   will be removed in version 7.0.
rm   rØ   s       r"   Úadd_callback_from_signalÚIOLoop.add_callback_from_signalŠ  s   € ô "Ó#Ð#r&   c                 ó0   • U R                   " U/UQ70 UD6  g)z�Calls the given callback on the next IOLoop iteration.

As of Tornado 6.0, this method is equivalent to `add_callback`.

.. versionadded:: 4.0
N©r¶   rØ   s       r"   Úspawn_callbackÚIOLoop.spawn_callback™  s   € ð 	×Ò˜(Ð4 TÒ4¨VÓ4r&   r¤   z0Union[Future[_T], concurrent.futures.Future[_T]]z
Future[_T]c                 ó¦   ^ ^• [        U[        5      (       a  UR                  UU 4S j5        g[        U5      (       d   e[	        UUU 4S j5        g)a	  Schedules a callback on the ``IOLoop`` when the given
`.Future` is finished.

The callback is invoked with one argument, the
`.Future`.

This method only accepts `.Future` objects and not other
awaitables (unlike most of Tornado where the two are
interchangeable).
c                 óP   >• TR                  [        R                  " TU 5      5      $ r   )Ú_run_callbackÚ	functoolsÚpartial©ÚfrÂ   r!   s    €€r"   r¥   Ú#IOLoop.add_future.<locals>.<lambda>»  s   ø€ ˜$×,Ñ,¬Y×->Ò->¸xÈÓ-KÔLr&   c                 ó(   >• TR                  TU 5      $ r   rÞ   ræ   s    €€r"   r¥   rè   Á  s   ø€ °t×7HÑ7HÈÐSTÔ7Ur&   N)r?   r   Úadd_done_callbackr   r   )r!   r¤   rÂ   s   ` `r"   r¬   ÚIOLoop.add_future¢  sE   ù€ ô �fœf×%Ñ%ð ×$Ñ$ÝLõô ˜V×$Ñ$Ð$Ð$ô % VÕ-UÕVr&   Úexecutor.c                 ó  ^• UcM  [        U S5      (       d0  SSKJn  [        R                  R                  U" 5       S-  S9U l        U R                  nUR                  " U/UQ76 n[        5       mU R                  UU4S j5        T$ )z×Runs a function in a ``concurrent.futures.Executor``. If
``executor`` is ``None``, the IO loop's default executor will be used.

Use `functools.partial` to pass keyword arguments to ``func``.

.. versionadded:: 5.0
Ú	_executorr   )Ú	cpu_counté   )Úmax_workersc                 ó   >• [        U T5      $ r   )r   )rç   Út_futures    €r"   r¥   Ú(IOLoop.run_in_executor.<locals>.<lambda>Ü  s   ø€ ¬L¸¸HÔ,Er&   )
ÚhasattrÚtornado.processrï   Ú
concurrentÚfuturesÚThreadPoolExecutorrî   Úsubmitr   r¬   )r!   rì   rž   rÃ   rï   Úc_futureró   s         @r"   Úrun_in_executorÚIOLoop.run_in_executorÃ  s}   ø€ ð ÑÜ˜4 ×-Ñ-Ý5ä!+×!3Ñ!3×!FÑ!FÙ!*£¨q¡ð "Gð "�”ð —~‘~ˆHØ—?’? 4Ð/¨$Ò/ˆô “8ˆØ�‰˜Ô"EÔFØˆr&   c                 ó   • Xl         g)zVSets the default executor to use with :meth:`run_in_executor`.

.. versionadded:: 5.0
N©rî   )r!   rì   s     r"   Úset_default_executorÚIOLoop.set_default_executorß  s	   € ð
 "�r&   c                 ó$  •  U" 5       nUb4  SSK Jn   UR                  U5      nU R                  X R                  5        gg! UR
                   a     gf = f! [        R                   a     g[         a    [        R                  " SUSS9   gf = f)zhRuns a callback with error handling.

.. versionchanged:: 6.0

   CancelledErrors are no longer logged.
Nr   )ÚgenúException in callback %rT©r«   )Útornador  r¢   r¬   Ú_discard_future_resultÚBadYieldErrorr\   ÚCancelledErrorr©   r	   Úerror)r!   rÂ   Úretr  s       r"   rã   ÚIOLoop._run_callbackæ  s–   € ð	OÙ“*ˆCØ‰Ý'ðFØ×-Ñ-¨cÓ2�Cð —O‘O C×)DÑ)DÕEð øð ×(Ñ(ó ñ ð	ûô ×%Ñ%ó 	ÙÜó 	OÜ�MŠMÐ4°hÈÔNð	Oús9   ‚A “A ¤A ÁAÁA ÁAÁA ÁBÁ-BÂBc                 ó$   • UR                  5         g)z;Avoid unhandled-exception warnings from spawned coroutines.N)r­   )r!   r¤   s     r"   r  ÚIOLoop._discard_future_result  s   € à�‰�r&   c                 óV   • [        U[        5      (       a  X4$ UR                  5       U4$ r   )r?   r/   r#   r•   s     r"   Úsplit_fdÚIOLoop.split_fd  s(   € ô$ �bœ#×ÑØ�6ˆMØ�y‰y‹{˜BˆÐr&   c                 óž   •  [        U[        5      (       a  [        R                  " U5        g UR                  5         g ! [         a     g f = fr   )r?   r/   Úosr(   ÚOSErrorr•   s     r"   Úclose_fdÚIOLoop.close_fd  s:   € ð	Ü˜"œc×"Ñ"Ü—’˜•à—‘•
øÜó 	Ùð	ús   ‚+? ®? ¿
AÁArç   c                 ó:   • U R                   R                  U5        g r   )Ú_pending_tasksÚadd©r!   rç   s     r"   Ú_register_taskÚIOLoop._register_task2  s   € Ø×Ñ×Ñ Õ"r&   c                 ó:   • U R                   R                  U5        g r   )r  Údiscardr  s     r"   Ú_unregister_taskÚIOLoop._unregister_task5  s   € Ø×Ñ×#Ñ# AÕ&r&   rÿ   )r   r5   r*   )T)Fr   )Lr+   r,   r-   r.   Ú__doc__ÚNONEÚREADÚWRITEÚERRORÚdictr`   Úsetr  Úclassmethodr   rE   ÚstaticmethodrK   rO   rS   ÚtypingÚoverloadrJ   Úboolr   rN   rj   rR   rq   rt   r   r
   rz   r~   r�   r(   r/   r   r‹   r2   r   r   r‘   r–   r™   rœ   Úfloatr½   r¸   rÉ   rÊ   Úobjectr·   rÐ   rÈ   r¹   r¶   rÛ   rß   r¬   r÷   rø   ÚExecutorr1   rü   r   rã   r   r  r   r  r  r  r  r0   Ú__classcell__)rG   s   @r"   r5   r5   H   sJ  ø† ñNðb €DØ€DØ€EØ€Eñ ›&Ðñ “U€Nàð	5Ø9ð	5ØEHð	5à	ö	5ó ð	5ð ó ó ð ô*ð óó ðð ‡_�_Øóó ó ðð ‡_�_Øñ˜$ð ¨(°8Ñ*<ô ó ó ðð ñ*˜$ð *¨(°8Ñ*<ô *ó ð*ôXô6$ð ó ó ð ð  ó&ó ð&ô
ð ð $ |Ñ"4ó ó ðð ð T¨,Ñ%7ó ó ðñ
! tð !°tõ !ñ$˜Tð $¨dõ $ð6 ‡_�_ðØðØ (¨#¨s¨°TÐ)9Ñ :ðØDGðà	óó ðð
 ‡_�_ðØðØ'¨¨S¨	°4¨Ñ8ðØBEðà	óó ðð
$Ø˜˜[Ð(Ñ)ð$Ø4<¸YÑ4Gð$ØQTð$à	ô$ð&$  s¨KÐ'7Ñ!8ð $À#ð $È$ô $ð$  s¨KÐ'7Ñ!8ð $¸Tô $ô$ô$ñJ'˜Xð J'°¸±ð J'È3õ J'ðX�eô ð'Bà˜˜x×1Ñ1Ð1Ñ2ð'Bð ð'Bð ð	'Bð
 ð'Bð 
ô'BðRLØðLØ&.ðLØ7:ðLØFIðLà	ôLðAØðAØ%-ðAØ69ðAØEHðAà	ôAð$$ fð $°ô $ð
$ Xð 
$°cð 
$ÀSð 
$ÈTô 
$ð$Ø ð$Ø),ð$Ø8;ð$à	ô$ð5 xð 5¸ð 5Àsð 5Ètô 5ðWàBðWð ˜L˜>¨4Ð/Ñ0ðWð 
ô	WðBà˜:×-Ñ-×6Ñ6Ñ7ðð �s˜B�wÑðð ð	ð
 
ôð8"¨Z×-?Ñ-?×-HÑ-Hð "ÈTô "ðO h¨r°3¨wÑ&7ð O¸Dô Oð<¨Vð ¸ô ðØ˜˜[Ð(Ñ)ðà	ˆs�E˜#˜{Ð*Ñ+Ð+Ñ	,ôð,˜5  kÐ!1Ñ2ð °tô ð(# ð #¨4ô #ð' &ð '¨T÷ 'ò 'r&   r5   c                   óh   • \ rS rSrSr/ SQrS\S\/ S4   S\SS4S	 jr	S
S S\
4S jrS
S S\
4S jrSrg)Ú_Timeouti9  z2An IOLoop timeout, a UNIX timestamp and a callback)rÁ   rÂ   Ú	tdeadlinerÁ   rÂ   NÚio_loopr   c                 ó®   • [        U[        R                  5      (       d  [        SU-  5      eXl        X l        U[        UR                  5      4U l        g )NrÅ   )	r?   rÆ   rÇ   rÌ   rÁ   rÂ   ÚnextÚ_timeout_counterr3  )r!   rÁ   rÂ   r4  s       r"   Ú__init__Ú_Timeout.__init__?  sJ   € ô ˜(¤G§L¡L×1Ñ1ÜÐ5¸Ñ@ÓAÐAØ ŒØ ŒàÜ�×)Ñ)Ó*ð
ˆ�r&   Úotherc                 ó4   • U R                   UR                   :  $ r   ©r3  ©r!   r:  s     r"   Ú__lt__Ú_Timeout.__lt__O  s   € Ø�~‰~ §¡Ñ/Ð/r&   c                 ó4   • U R                   UR                   :*  $ r   r<  r=  s     r"   Ú__le__Ú_Timeout.__le__R  s   € Ø�~‰~ §¡Ñ0Ð0r&   )rÂ   rÁ   r3  )r+   r,   r-   r.   r!  Ú	__slots__r-  r   r5   r8  r,  r>  rA  r0   r   r&   r"   r2  r2  9  s`   † Ù<ò 6€Ið

Øð

Ø)1°"°d°(Ñ);ð

ØFLð

à	ô

ð 0˜Jð 0¨4ô 0ð1˜Jð 1¨4÷ 1r&   r2  c            	       ó®   • \ rS rSrSr SS\/ \\   4   S\\	R                  \4   S\SS4S jjrSS	 jrSS
 jrS\4S jrSS jrSS jrS\SS4S jrSrg)ÚPeriodicCallbackiV  a  Schedules the given callback to be called periodically.

The callback is called every ``callback_time`` milliseconds when
``callback_time`` is a float. Note that the timeout is given in
milliseconds, while most other time-related functions in Tornado use
seconds. ``callback_time`` may alternatively be given as a
`datetime.timedelta` object.

If ``jitter`` is specified, each callback time will be randomly selected
within a window of ``jitter * callback_time`` milliseconds.
Jitter can be used to reduce alignment of events with similar periods.
A jitter of 0.1 means allowing a 10% variation in callback time.
The window is centered on ``callback_time`` so the total number of calls
within a given interval should not be significantly affected by adding
jitter.

If the callback runs for longer than ``callback_time`` milliseconds,
subsequent invocations will be skipped to get back on schedule.

`start` must be called after the `PeriodicCallback` is created.

.. versionchanged:: 5.0
   The ``io_loop`` argument (deprecated since version 4.1) has been removed.

.. versionchanged:: 5.1
   The ``jitter`` argument is added.

.. versionchanged:: 6.2
   If the ``callback`` argument is a coroutine, and a callback runs for
   longer than ``callback_time``, subsequent invocations will be skipped.
   Previously this was only true for regular functions, not coroutines,
   which were "fire-and-forget" for `PeriodicCallback`.

   The ``callback_time`` argument now accepts `datetime.timedelta` objects,
   in addition to the previous numeric milliseconds.
rÂ   Úcallback_timeÚjitterr   Nc                 óÞ   • Xl         [        U[        R                  5      (       a  U[        R                  " SS9-  U l        OUS::  a  [        S5      eX l        X0l        SU l        S U l        g )Nr7   )Úmillisecondsr   z4Periodic callback must have a positive callback_timeF)	rÂ   r?   rÉ   rÊ   rF  Ú
ValueErrorrG  Ú_runningÚ_timeout)r!   rÂ   rF  rG  s       r"   r8  ÚPeriodicCallback.__init__|  sb   € ð !ŒÜ�m¤X×%7Ñ%7×8Ñ8Ø!.´×1CÒ1CÐQRÑ1SÑ!SˆDÕà Ó!Ü Ð!WÓXÐXØ!.ÔØŒØˆŒØˆ�r&   c                 ó¢   • [         R                  5       U l        SU l        U R                  R	                  5       U l        U R                  5         g)zStarts the timer.TN)r5   rJ   r4  rK  r¸   Ú_next_timeoutÚ_schedule_nextr    s    r"   r™   ÚPeriodicCallback.start�  s:   € ô
 —~‘~Ó'ˆŒØˆŒØ!Ÿ\™\×.Ñ.Ó0ˆÔØ×ÑÕr&   c                 ó†   • SU l         U R                  b-  U R                  R                  U R                  5        SU l        gg)zStops the timer.FN)rK  rL  r4  r¹   r    s    r"   rœ   ÚPeriodicCallback.stop—  s5   € àˆŒØ�=‰=Ñ$Ø�L‰L×'Ñ'¨¯©Ô6Ø ˆD�Mð %r&   c                 ó   • U R                   $ )zVReturns ``True`` if this `.PeriodicCallback` has been started.

.. versionadded:: 4.1
)rK  r    s    r"   Ú
is_runningÚPeriodicCallback.is_runningž  s   € ð
 �}‰}Ðr&   c              ƒ   ó:  #   • U R                   (       d  g  U R                  5       nUb  [        U5      (       a
  UI S h  v•N   U R                  5         g  N! [         a#    [        R
                  " SU R                  SS9   N?f = f! U R                  5         f = f7f)Nr  Tr  )rK  rÂ   r   r©   r	   r
  rP  )r!   Úvals     r"   Ú_runÚPeriodicCallback._run¥  s|   é € Ø�}�}Øð	"Ø—-‘-“/ˆCØ‰¤;¨s×#3Ñ#3Ø—	�	ð ×ÑÕ!ñ	 øÜó 	TÜ�MŠMÐ4°d·m±mÈdÔSð	Tûð ×ÑÕ!üsD   ‚B–(A ¾A¿A ÁBÁA Á*BÂ B ÂBÂB ÂBÂBc                 óä   • U R                   (       a_  U R                  U R                  R                  5       5        U R                  R	                  U R
                  U R                  5      U l        g g r   )rK  Ú_update_nextr4  r¸   r·   rO  rY  rL  r    s    r"   rP  ÚPeriodicCallback._schedule_next±  sK   € Ø�=�=Ø×Ñ˜dŸl™l×/Ñ/Ó1Ô2Ø ŸL™L×4Ñ4°T×5GÑ5GÈÏÉÓSˆD�Mð r&   Úcurrent_timec                 ób  • U R                   S-  nU R                  (       a+  USU R                  [        R                  " 5       S-
  -  -   -  nU R                  U::  a?  U =R                  [        R
                  " XR                  -
  U-  5      S-   U-  -  sl        g U =R                  U-  sl        g )Ng     @�@r7   g      à?)rF  rG  ÚrandomrO  ÚmathÚfloor)r!   r^  Úcallback_time_secs      r"   r\  ÚPeriodicCallback._update_next¶  sœ   € Ø ×.Ñ.°Ñ7ÐØ�;�;à  d§k¡k´V·]²]³_ÀsÑ5JÑ&KÑ!LÑLÐØ×Ñ Ó-ð
 ×ÒÜ—
’
˜L×+=Ñ+=Ñ=ÐARÑRÓSÐVWÑWØ!ñ#"ñ "Öð$ ×ÒÐ"3Ñ3Ör&   )rO  rK  rL  rÂ   rF  r4  rG  )r   r*   )r+   r,   r-   r.   r!  r   r   r   r   rÉ   rÊ   r-  r8  r™   rœ   r,  rU  rY  rP  r\  r0   r   r&   r"   rE  rE  V  s‹   † ñ#ðR ñ	à˜2˜x¨	Ñ2Ð2Ñ3ðð ˜X×/Ñ/°Ð6Ñ7ðð ð	ð
 
õô"ô!ð˜Dô ô
"ôTð
4¨ð 4°4÷ 4r&   rE  )1r!  r\   Úconcurrent.futuresr÷   rÉ   rä   rÆ   r  rª   r¸   ra  r`  rg   Úinspectr   Útornado.concurrentr   r   r   r   r   Útornado.logr	   Útornado.utilr
   r   r   r*  r   r   r   r   r   r   r   r   ÚTYPE_CHECKINGr   r   r   Útyping_extensionsr   r.  r   r1   r2   r5   r2  rE  r   r&   r"   Ú<module>rl     s´   ðñ ó Û Û Û Û Û 	Û 
Û Û Û Û Ý ÷õ õ  ß BÑ Bã ß R× RÓ Rà	××ß&Ñ&æ*à€Hô�(ô ñ ˆTƒ]€ÙˆT˜Ñ%€ôn'ˆ\ô n'ôb1ˆvô 1ô:|4�võ |4r&   