
    h                        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'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      r0 " S S5      r1g)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	TypedDict)Protocolc                   ,    \ rS rSrS\4S jrSS jrSrg)_Selectable<   returnc                     g N selfs    aC:\Users\julio\OneDrive\Documentos\Trabajo\Ideas Frescas\venv\Lib\site-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IOLoopH   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())

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[        T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super	configure)clsr;   r<   r>   	__class__s       r#   rF   IOLoop.configure   sT     	=dC   &DdD!!*T*K*KVWW$)&)r'   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
)r6   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)r6   clear_currentr    r'   r#   clear_instanceIOLoop.clear_instance   s     	r'   c                      g r   r    r    r'   r#   rK   IOLoop.current        	r'   rL   c                     g r   r    rL   s    r#   rK   rW      rX   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_looprD   new_event_loopset_event_loopr6   _ioloop_for_asyncioKeyErrorr?   r\   )rL   loopr\   rK   s       r#   rK   rW      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#   rO   IOLoop.make_current"  s'    ( 	D	

 	r'   c                     [        5       er   NotImplementedErrorr!   s    r#   rk   IOLoop._make_current=  s    !##r'   c                  `    [         R                  " S[        SS9  [        R	                  5         g)zClears 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 deprecatedre   rf   N)rh   ri   rj   r6   _clear_currentr    r'   r#   rS   IOLoop.clear_currentA  s'     	)	

 	r'   c                  R    [         R                  SS9n U b  U R                  5         g g )NFrZ   )r6   rK   _clear_current_hook)olds    r#   rr   IOLoop._clear_currentR  s(    nnen,?##% 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#   ru   IOLoop._clear_current_hookX  s    
 	r'   c                     [         $ r   )r6   )rG   s    r#   configurable_baseIOLoop.configurable_base_  s    r'   c                     SSK Jn  U$ )Nr   )AsyncIOLoop)r?   r~   )rG   r~   s     r#   configurable_defaultIOLoop.configurable_defaultc  s    8r'   rO   c                 4    U(       a  U R                  5         g g r   )rk   )r"   rO   s     r#   
initializeIOLoop.initializei  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.
rn   )r"   r   s     r#   r)   IOLoop.closem  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.
rn   r   s       r#   r   r     s    " "##r'   c                     [        5       e)zChanges the events we listen for ``fd``.

.. versionchanged:: 4.0
   Added the ability to pass file-like objects in addition to
   raw file descriptors.
rn   )r"   r   r   s      r#   update_handlerIOLoop.update_handler       "##r'   c                     [        5       e)zStop listening for events on ``fd``.

.. versionchanged:: 4.0
   Added the ability to pass file-like objects in addition to
   raw file descriptors.
rn   r"   r   s     r#   remove_handlerIOLoop.remove_handler  r   r'   c                     [        5       e)zStarts 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.
rn   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.
rn   r!   s    r#   stopIOLoop.stop  s     "##r'   functimeoutc                 0  ^ ^^ [         R                  (       a  [        S[        [           [
        S.5      nSS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#  TS   (       a  [        S	U-  5      e[        S
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``.

FutureCell)futuretimeout_calledNFc                  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_yieldedr   c                 $   > TR                  5       $ r   )r   )r   r"   s    r#   <lambda>.IOLoop.run_sync.<locals>.run.<locals>.<lambda>  s    $))+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4F V$$,2K) (C,/K)NN6*x(444OOK13MN  9h(+H%#C89s   A4 48B/.B/c                  r   > ST S'   T S   c   eT S   R                  5       (       d  TR                  5         g g )NTr   r   )cancelr   )r   r"   s   r#   timeout_callback)IOLoop.run_sync.<locals>.timeout_callback  sC    04,-
 #8,888"8,3355IIK 6r'   r   r   z$Operation timed out after %s secondsz+Event loop stopped before Future completed.r+   )typingTYPE_CHECKINGr   r   r   booladd_callbackadd_timeouttimer   remove_timeout	cancelleddoner   rD   r   )r"   r   r   r   r   r   timeout_handler   s   ``     @r#   run_syncIOLoop.run_sync  s   @ "&)9TRJ "&?	O 	O* 	#	  	  "--diikG.CEUVN

/8$000x **,,K4I4N4N4P4P+,"#IG#STT ##PQQ8$++--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     yy{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_timeout3  s    @ h--<<DTDV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_later\  s*     ||DIIK%/KDKF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_atk  s      @@@@r'   c                     [        5       e)zCancels 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.
rn   )r"   r   s     r#   r   IOLoop.remove_timeout}  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.
rn   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.
rn   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)zCalls 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     	(4T4V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    t7H7HST7Ur'   N)r@   r   add_done_callbackr   r   )r"   r   r   s   ` `r#   r   IOLoop.add_future  sE     ff%% $$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$ )zRuns 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2C OOC)D)DE  ((  	 %% 	 	OMM4h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@   r0   r$   r   s     r#   split_fdIOLoop.split_fd  s(    $ b#6Myy{Br'   c                      [        U[        5      (       a  [        R                  " U5        g UR                  5         g ! [         a     g f = fr   )r@   r0   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_task:  s    "r'   c                 :    U R                   R                  U5        g r   )r  discardr   s     r#   _unregister_taskIOLoop._unregister_task=  s    ##A&r'   r  )r   r6   r+   )T)Fr   )Lr,   r-   r.   r/   __doc__NONEREADWRITEERRORdictra   setr  classmethodr   rF   staticmethodrL   rP   rT   r   overloadrK   r   r   rO   rk   rS   rr   ru   r   r
   r{   r   r   r)   r0   r   r   r3   r   r   r   r   r   r   floatr   r   r   r   objectr   r   r   r   r   r   r   r   r   r   Executorr2   r  r  r   r   r  r   r  r  r!  r%  r1   __classcell__)rH   s   @r#   r6   r6   H   sJ   K\ DDEE & UN	*9	*EH	*		* 	*    *   __   __$ (8*<    *$ *(8*< * *X6$      & &
 $|"4   T,%7  
!t !t !$T $d $6 __ (#sT)9 :DG	 
 __'S	48BE	 
$[()$4<Y4G$QT$	$&$sK'7!8 $# $$ $$sK'7!8 $T $$$U.X U. U.3 U.n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;$	$5x 5 5s 5t 5WBW L>4/0W 
	WB:--667 sBw 	
 
8"Z-?-?-H-H "T "Ohr3w&7 OD O<V  [()	sE#{*++	,,5k!12 t (# #4 #'& 'T ' 'r'   r6   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)_TimeoutiA  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_counterr7  )r"   r   r   r8  s       r#   __init___Timeout.__init__G  sJ     (GLL115@AA  ))*
r'   otherc                 4    U R                   UR                   :  $ r   r7  r"   r>  s     r#   __lt___Timeout.__lt__W  s    ~~//r'   c                 4    U R                   UR                   :*  $ r   r@  rA  s     r#   __le___Timeout.__le__Z  s    ~~00r'   )r   r   r7  )r,   r-   r.   r/   r'  	__slots__r1  r   r6   r<  r   rB  rE  r1   r    r'   r#   r6  r6  A  s`    < 6I



)1"d();

FL

	

 0J 04 01J 14 1r'   r6  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)PeriodicCallbacki^  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 )Nr8   )millisecondsr   z4Periodic callback must have a positive callback_timeF)	r   r@   r   r   rJ  
ValueErrorrK  _running_timeout)r"   r   rJ  rK  s       r#   r<  PeriodicCallback.__init__  sb     !mX%7%788!.1C1CQR1S!SD! !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)r6   rK   r8  rO  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)rO  rP  r8  r   r!   s    r#   r   PeriodicCallback.stop  s5    ==$LL''6 DM %r'   c                     U R                   $ )zVReturns ``True`` if this `.PeriodicCallback` has been started.

.. versionadded:: 4.1
)rO  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  )rO  r   r   r   r	   r  rT  )r"   vals     r#   _runPeriodicCallback._run  s|     }}	"--/C;s#3#3		 !	  	TMM4dmmd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   )rO  _update_nextr8  r   r   rS  r]  rP  r!   s    r#   rT  PeriodicCallback._schedule_next  sK    ==dll//12 LL44T5G5GSDM 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     @@r8   g      ?)rJ  rK  randomrS  mathfloor)r"   rb  callback_time_secs      r#   r`  PeriodicCallback._update_next  s     ..7;;dkkV]]_s5J&K!LL-
 

L+=+==ARRSVWW!#" "$ "33r'   )rS  rO  rP  r   rJ  r8  rK  )r   r+   )r,   r-   r.   r/   r'  r   r   r   r   r   r   r1  r<  r   r   r   rY  r]  rT  r`  r1   r    r'   r#   rI  rI  ^  s    #R 	2x	223 X//67 	
 
"!D 
"T
4 44 4r'   rI  )2r'  r]   concurrent.futuresr   r   r   r   r  r   r   re  rd  rh   inspectr   tornado.concurrentr   r   r   r   r   tornado.logr	   tornado.utilr
   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   typing_extensionsr   r2  r   r2   r3   r6   r6  rI  r    r'   r#   <module>ro     s          	 
         B B  R R R	11*H(  T]T%v'\ v'r1 1:|4 |4r'   