
    2 fҏ                        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ZddlmZ ddlmZmZmZmZmZ ddlmZ ddlmZmZmZ ddlZddlmZmZmZmZm Z m!Z!m"Z"m#Z# ej$        rddlm%Z%m&Z&m'Z' dd	l(m)Z) ne*Z) G d
 de)          Z+ e!d          Z, e!de+          Z- G d de          Z. G d de*          Z/ G d de*          Z0dS )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                   "    e Zd ZdefdZddZdS )_Selectablereturnc                     d S N selfs    D/var/www/equiseq/venv/lib/python3.11/site-packages/tornado/ioloop.pyfilenoz_Selectable.fileno=           Nc                     d S r   r   r   s    r!   closez_Selectable.close@   r#   r$   r   N)__name__
__module____qualname__intr"   r&   r   r$   r!   r   r   <   sC                 r$   r   _T_S)boundc            
       ^    e Zd ZdZdZdZdZdZ e            Z	 e
            Zeddded	d
f fd            ZedJd            ZdKdZedKd            Zej        edJd                        Zej        edLded	ed          fd                        ZedLded	ed          fd            ZdKdZdKdZedKd            ZedKd            ZdKdZed	ee         fd            Zed	ee         fd            Z dLded	d
fdZ!dMded	d
fdZ"ej        d e#d!e$e#e#gd
f         d"e#d	d
fd#            Z%ej        d e&d!e$e&e#gd
f         d"e#d	d
fd$            Z%d e'e#e(f         d!e$d%         d"e#d	d
fd&Z%d e'e#e(f         d"e#d	d
fd'Z)d e'e#e(f         d	d
fd(Z*dKd)Z+dKd*Z,dNd+e$d,ee-         d	efd-Z.d	e-fd.Z/d/e'e-e0j1        f         d0e$d1eded	e2f
d2Z3d3e-d0e$d1eded	e2f
d4Z4d5e-d0e$d1eded	e2f
d6Z5d,e2d	d
fd7Z6d0e$d1eded	d
fd8Z7d0e$d1eded	d
fd9Z8d0e$d1eded	d
fd:Z9d;d<d0e$d=gd
f         d	d
fd>Z:d?ee;j<        j=                 d+e$d@e>f         d1ed	d=fdAZ?d?e;j<        j=        d	d
fdBZ@d0e$g ef         d	d
fdCZAd;eBd	d
fdDZCd e'e#e(f         d	eDe#e'e#e(f         f         fdEZEd e'e#e(f         d	d
fdFZFdGeBd	d
fdHZGdGeBd	d
fdIZH xZIS )OIOLoopa  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                    ddl m} t          |t                    rt	          |          }t          |t
                    rt          ||          st          d           t          t          |           j
        |fi | d S )Nr   )BaseAsyncIOLoopz5only AsyncIOLoop is allowed when asyncio is available)tornado.platform.asyncior7   
isinstancestrr   type
issubclassRuntimeErrorsuperr0   	configure)clsr4   r5   r7   	__class__s       r!   r?   zIOLoop.configure   s     	=<<<<<dC   	' &&DdD!! 	X*T?*K*K 	XVWWW$fc$T44V44444r$   c                  4    t                                           S )aK  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
        )r0   currentr   r$   r!   instancezIOLoop.instance   s    ( ~~r$   c                 .    |                                   dS )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!   installzIOLoop.install   s     	r$   c                  8    t                                            dS )ak  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)r0   clear_currentr   r$   r!   clear_instancezIOLoop.clear_instance   s     	r$   c                      d S r   r   r   r$   r!   rC   zIOLoop.current   	     	r$   TrD   c                     d S r   r   rD   s    r!   rC   zIOLoop.current   rL   r$   c                    	 t          j                    }n<# t          $ r/ | sY dS t          j                    }t          j        |           Y nw xY w	 t
          j        |         S # t          $ r | rddlm	}  |            }nd}Y nw xY w|S )aC  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_loopr=   new_event_loopset_event_loopr0   _ioloop_for_asyncioKeyErrorr8   rP   )rD   looprP   rC   s       r!   rC   zIOLoop.current   s    2	))++DD 	) 	) 	) tt)++D"4(((((	)	-d33 	 	 	 DDDDDD)/++	 s&    A'AAA% %BBc                 f    t          j        dt          d           |                                  dS )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!   rF   zIOLoop.make_current%  s@    ( 	D	
 	
 	
 	

 	r$   c                     t                      r   NotImplementedErrorr   s    r!   r_   zIOLoop._make_current@  s    !###r$   c                  p    t          j        dt          d           t                                           dS )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 deprecatedrY   rZ   N)r\   r]   r^   r0   _clear_currentr   r$   r!   rI   zIOLoop.clear_currentD  s@     	)	
 	
 	
 	

 	r$   c                  l    t                               d          } | |                                  d S d S )NFrN   )r0   rC   _clear_current_hook)olds    r!   rd   zIOLoop._clear_currentU  s9    nnen,,?##%%%%% ?r$   c                     dS )zInstance method called when an IOLoop ceases to be current.

        May be overridden by subclasses as a counterpart to make_current.
        Nr   r   s    r!   rf   zIOLoop._clear_current_hook[  s	    
 	r$   c                     t           S r   )r0   )r@   s    r!   configurable_basezIOLoop.configurable_baseb  s    r$   c                     ddl m} |S )Nr   )AsyncIOLoop)r8   rl   )r@   rl   s     r!   configurable_defaultzIOLoop.configurable_defaultf  s    888888r$   rF   c                 6    |r|                                   d S d S r   )r_   )r    rF   s     r!   
initializezIOLoop.initializel  s,     	!     	! 	!r$   Fall_fdsc                     t                      )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.
        ra   )r    rp   s     r!   r&   zIOLoop.closep  s    2 "###r$   fdhandlereventsc                     d S r   r   r    rr   rs   rt   s       r!   add_handlerzIOLoop.add_handler  	     	r$   c                     d S r   r   rv   s       r!   rw   zIOLoop.add_handler  rx   r$   ).Nc                     t                      )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.
        ra   rv   s       r!   rw   zIOLoop.add_handler  s    " "###r$   c                     t                      )zChanges the events we listen for ``fd``.

        .. versionchanged:: 4.0
           Added the ability to pass file-like objects in addition to
           raw file descriptors.
        ra   )r    rr   rt   s      r!   update_handlerzIOLoop.update_handler       "###r$   c                     t                      )zStop listening for events on ``fd``.

        .. versionchanged:: 4.0
           Added the ability to pass file-like objects in addition to
           raw file descriptors.
        ra   r    rr   s     r!   remove_handlerzIOLoop.remove_handler  r}   r$   c                     t                      )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.
        ra   r   s    r!   startzIOLoop.start  s     "###r$   c                     t                      )a  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.
        ra   r   s    r!   stopzIOLoop.stop  s     "###r$   functimeoutc                     dgd fd}                      |           |2d fd}                                                      |z   |          }                                  |                     |           d         J d                                         sd                                         st          d|z            d                                         S )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``.
        Nr   c                     	              } | ddl m}  ||           } t          |           r| d<   nmt                      }|d<   |                    |            nD# t
          $ r7 t                      }|d<   t          |t          j                               Y nw xY wd         J 	                    d         fd           d S )Nr   )convert_yieldedc                 ,                                     S r   )r   )futurer    s    r!   <lambda>z.IOLoop.run_sync.<locals>.run.<locals>.<lambda>  s    499;; r$   )
tornado.genr   r   r   
set_result	Exceptionr   sysexc_info
add_future)resultr   futr   future_cellr    s      r!   runzIOLoop.run_sync.<locals>.run  s   +%;;;;;;,_V44F V$$ +%+KNN ((C%(KNNN6****  9 9 9hh!$A#C888889 q>---OOKN,F,F,F,FGGGGGs   A >BBc                  |     d         J  d                                          s                                 d S d S )Nr   )cancelr   )r   r    s   r!   timeout_callbackz)IOLoop.run_sync.<locals>.timeout_callback  sH    
 #1~111"1~,,..  IIKKKKK   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_synczIOLoop.run_sync  s5   @ f	H 	H 	H 	H 	H 	H 	H 	H* 	#              "--diikkG.CEUVVN

///1~)))q>##%% 	Q[^-@-@-B-B 	QEOPPP1~$$&&&r$   c                 (    t          j                     S )a  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   zIOLoop.time  s     y{{r$   deadlinecallbackargsc                 $   t          |t          j                  r | j        ||g|R i |S t          |t          j                  r9 | j        |                                 |                                z   |g|R i |S t          d|z            )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)	r9   numbersRealcall_atdatetime	timedeltar   total_seconds	TypeError)r    r   r   r   r5   s        r!   r   zIOLoop.add_timeout+  s    @ h-- 	B4<(DTDDDVDDD("455 	B4<		h44666CG  KQ   5@AAAr$   delayc                 P     | j         |                                 |z   |g|R i |S )a  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   r5   s        r!   
call_laterzIOLoop.call_laterT  s5     t|DIIKK%/KDKKKFKKKr$   whenc                 &     | j         ||g|R i |S )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   r5   s        r!   r   zIOLoop.call_atc  s)       th@@@@@@@r$   c                     t                      )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.
        ra   )r    r   s     r!   r   zIOLoop.remove_timeoutu  r}   r$   c                     t                      )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.
        ra   r    r   r   r5   s       r!   r   zIOLoop.add_callback~  s     "###r$   c                     t                      )a  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.
        ra   r   s       r!   add_callback_from_signalzIOLoop.add_callback_from_signal  s     "###r$   c                 (     | j         |g|R i | dS )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_callbackzIOLoop.spawn_callback  s-     	(4T444V44444r$   r   z0Union[Future[_T], concurrent.futures.Future[_T]]z
Future[_T]c                      t          |t                    r|                     fd           dS t          |          sJ t	          | fd           dS )aA  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                 T                         t          j        |                     S r   )_run_callback	functoolspartialfr   r    s    r!   r   z#IOLoop.add_future.<locals>.<lambda>  s"    $,,Y->x-K-KLL r$   c                 0                         |           S r   r   r   s    r!   r   z#IOLoop.add_future.<locals>.<lambda>  s    t7H7HST7U7U r$   N)r9   r   add_done_callbackr   r   )r    r   r   s   ` `r!   r   zIOLoop.add_future  s     ff%% 	W $$LLLLL     V$$$$$ %V-U-U-U-U-UVVVVVr$   executor.c                    |Mt          | d          s6ddlm} t          j                             |            dz            | _        | j        } |j        |g|R  }t                      | 	                    |fd           S )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
        N	_executorr   )	cpu_count   )max_workersc                 $    t          |           S r   )r   )r   t_futures    r!   r   z(IOLoop.run_in_executor.<locals>.<lambda>  s    LH,E,E r$   )
hasattrtornado.processr   
concurrentfuturesThreadPoolExecutorr   submitr   r   )r    r   r   r   r   c_futurer   s         @r!   run_in_executorzIOLoop.run_in_executor  s     4-- 555555!+!3!F!F!*q "G " " ~H"8?4/$/// 88"E"E"E"EFFFr$   c                     || _         dS )zfSets the default executor to use with :meth:`run_in_executor`.

        .. versionadded:: 5.0
        N)r   )r    r   s     r!   set_default_executorzIOLoop.set_default_executor  s    
 "r$   c                 &   	  |            }|Jddl m} 	 |                    |          }|                     || j                   dS # |j        $ r Y dS w xY wdS # t          j        $ r Y dS t          $ r t          j
        d|d           Y dS w xY w)zRuns 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BadYieldErrorrQ   CancelledErrorr   r	   error)r    r   retr   s       r!   r   zIOLoop._run_callback  s    	O(**C''''''F--c22C OOC)DEEEEE (    DD	   % 	 	 	DD 	O 	O 	OM4hNNNNNNN	Os9   A A A 
AA AA B, BBc                 .    |                                  dS )z;Avoid unhandled-exception warnings from spawned coroutines.N)r   )r    r   s     r!   r   zIOLoop._discard_future_result  s    r$   c                 `    t          |t                    r||fS |                                |fS r   )r9   r+   r"   r   s     r!   split_fdzIOLoop.split_fd  s1    $ b# 	r6Myy{{Br$   c                     	 t          |t                    rt          j        |           d S |                                 d S # t          $ r Y d S w xY wr   )r9   r+   osr&   OSErrorr   s     r!   close_fdzIOLoop.close_fd  s]    	"c"" 




 	 	 	DD	s   )A A 
AAr   c                 :    | j                             |           d S r   )_pending_tasksaddr    r   s     r!   _register_taskzIOLoop._register_task2  s    """""r$   c                 :    | j                             |           d S r   )r   discardr   s     r!   _unregister_taskzIOLoop._unregister_task5  s    ##A&&&&&r$   )r   r0   r'   )T)Fr   )Jr(   r)   r*   __doc__NONEREADWRITEERRORdictrU   setr   classmethodr   r?   staticmethodrD   rG   rJ   typingoverloadrC   boolr   rF   r_   rI   rd   rf   r   r
   rj   rm   ro   r&   r+   r   rw   r-   r   r   r|   r   r   r   floatr   r   r   r   objectr   r   r   r   r   r   r   r   r   r   Executorr,   r   r   r   r   r   r   r   r   r   r   __classcell__)rA   s   @r!   r0   r0   H   s       N Nb DDEE $&& SUUN	59	5EH	5		5 	5 	5 	5 	5 [	5       \ *       \ _   \ _ _ $ (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 $ $ $ $$ $ $ $$ $ $ $J' J'X J' J'3 J' J' J' J'Xe    'Bx112'B 'B 	'B
 'B 
'B 'B 'B 'BRLL&.L7:LFIL	L L L LAA%-A69AEHA	A A A A$$f $ $ $ $ $
$X 
$c 
$S 
$T 
$ 
$ 
$ 
$$ $),$8;$	$ $ $ $5x 5 5s 5t 5 5 5 5WBW L>4/0W 
	W W W WB:-67 sBw 	
 
   8"Z-?-H "T " " " "Ohr3w&7 OD O O O O<V     [()	sE#{*++	,   ,5k!12 t    (# #4 # # # #'& 'T ' ' ' ' ' ' ' 'r$   r0   c                   b    e Zd ZdZg dZdedeg df         deddfdZd	d de	fd
Z
d	d de	fdZdS )_Timeoutz2An IOLoop timeout, a UNIX timestamp and a callback)r   r   	tdeadliner   r   Nio_loopr   c                     t          |t          j                  st          d|z            || _        || _        |t          |j                  f| _        d S )Nr   )	r9   r   r   r   r   r   next_timeout_counterr  )r    r   r   r  s       r!   __init__z_Timeout.__init__?  sY     (GL11 	B5@AAA  )**
r$   otherc                 "    | j         |j         k     S r   r  r    r  s     r!   __lt__z_Timeout.__lt__O  s    ~//r$   c                 "    | j         |j         k    S r   r
  r  s     r!   __le__z_Timeout.__le__R  s    ~00r$   )r(   r)   r*   r   	__slots__r   r   r0   r  r   r  r  r   r$   r!   r  r  9  s        << 655I



)1"d();

FL

	

 

 

 

 0J 04 0 0 0 01J 14 1 1 1 1 1 1r$   r  c            	           e Zd ZdZ	 ddeg ee         f         deej	        e
f         de
ddfdZdd	Zdd
ZdefdZddZddZde
ddfdZdS )PeriodicCallbacka  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   r   callback_timejitterr   Nc                     || _         t          |t          j                  r|t          j        d          z  | _        n|dk    rt          d          || _        || _        d| _        d | _        d S )Nr1   )millisecondsr   z4Periodic callback must have a positive callback_timeF)	r   r9   r   r   r  
ValueErrorr  _running_timeout)r    r   r  r  s       r!   r  zPeriodicCallback.__init__|  sz     !mX%788 	/!.1CQR1S1S1S!SD!! !WXXX!.Dr$   c                     t                                           | _        d| _        | j                                        | _        |                                  dS )zStarts the timer.TN)r0   rC   r  r  r   _next_timeout_schedule_nextr   s    r!   r   zPeriodicCallback.start  sJ    
 ~~''!\..00r$   c                 r    d| _         | j        (| j                            | j                   d| _        dS dS )zStops the timer.FN)r  r  r  r   r   s    r!   r   zPeriodicCallback.stop  s<    =$L''666 DMMM %$r$   c                     | j         S )zfReturns ``True`` if this `.PeriodicCallback` has been started.

        .. versionadded:: 4.1
        )r  r   s    r!   
is_runningzPeriodicCallback.is_running  s    
 }r$   c                 ,  K   | j         sd S 	 |                                 }|t          |          r| d {V  n,# t          $ r t	          j        d| j        d           Y nw xY w|                                  d S # |                                  w xY w)Nr   Tr   )r  r   r   r   r	   r   r  )r    vals     r!   _runzPeriodicCallback._run  s      } 	F	"--//C;s#3#3							 	T 	T 	TM4dmdSSSSSS	T !!!!!D!!!!s&   -; A= &A$!A= #A$$A= =Bc                     | j         rX|                     | j                                                   | j                            | j        | j                  | _        d S d S r   )r  _update_nextr  r   r   r  r!  r  r   s    r!   r  zPeriodicCallback._schedule_next  s]    = 	Tdl//11222 L44T5GSSDMMM	T 	Tr$   current_timec                    | j         dz  }| j        r$|d| j        t          j                    dz
  z  z   z  }| j        |k    r5| xj        t	          j        || j        z
  |z            dz   |z  z  c_        d S | xj        |z  c_        d S )Ng     @@r1   g      ?)r  r  randomr  mathfloor)r    r$  callback_time_secs      r!   r#  zPeriodicCallback._update_next  s     .7; 	MdkV]__s5J&K!LL--
 
L4+==ARRSSVWW!#" "$ "33r$   )r   r'   )r(   r)   r*   r   r   r   r   r   r   r   r   r  r   r   r   r  r!  r  r#  r   r$   r!   r  r  V  s       # #R 	 2x	223 X/67 	
 
   "   ! ! ! !D    
" 
" 
" 
"T T T T
4 44 4 4 4 4 4 4r$   r  )1r   rQ   concurrent.futuresr   r   r   r   r   r   r   r'  r&  r\   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   r,   r-   r0   r  r  r   r$   r!   <module>r1     st                				 



                               B B B B B B B B B B  R R R R R R R R R R R R R R R R R R R R	 &&&&&&&&&&*******H    (    WT]]WT%%%n' n' n' n' n'\ n' n' n'b1 1 1 1 1v 1 1 1:|4 |4 |4 |4 |4v |4 |4 |4 |4 |4r$   