
    Mh-                        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'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          Z0 G d d          Z1d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	TypedDict)Protocolc                   "    e Zd ZdefdZddZdS )_Selectablereturnc                     d S N selfs    N/var/www/html/test/jupyter/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())

    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                      j	        |fi | d S )Nr   )BaseAsyncIOLoopz5only AsyncIOLoop is allowed when asyncio is available)
tornado.platform.asyncior8   
isinstancestrr   type
issubclassRuntimeErrorsuper	configure)clsr5   r6   r8   	__class__s       r"   r@   zIOLoop.configure   s     	=<<<<<dC   	' &&DdD!! 	X*T?*K*K 	XVWWW$))&)))))r%   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
        )r1   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)r1   clear_currentr   r%   r"   clear_instancezIOLoop.clear_instance   s     	r%   c                      d S r   r   r   r%   r"   rD   zIOLoop.current   	     	r%   TrE   c                     d S r   r   rE   s    r"   rD   zIOLoop.current   rM   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_loopr1   _ioloop_for_asyncioKeyErrorr9   rQ   )rE   looprQ   rD   s       r"   rD   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"   rG   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 deprecatedrZ   r[   N)r]   r^   r_   r1   _clear_currentr   r%   r"   rJ   zIOLoop.clear_currentA  s@     	)	
 	
 	
 	

 	r%   c                  l    t                               d          } | |                                  d S d S )NFrO   )r1   rD   _clear_current_hook)olds    r"   re   zIOLoop._clear_currentR  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"   rg   zIOLoop._clear_current_hookX  s	    
 	r%   c                     t           S r   )r1   )rA   s    r"   configurable_basezIOLoop.configurable_base_  s    r%   c                     ddl m} |S )Nr   )AsyncIOLoop)r9   rm   )rA   rm   s     r"   configurable_defaultzIOLoop.configurable_defaultc  s    888888r%   rG   c                 6    |r|                                   d S d S r   )r`   )r!   rG   s     r"   
initializezIOLoop.initializei  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.
        rb   )r!   rq   s     r"   r'   zIOLoop.closem  s    2 "###r%   fdhandlereventsc                     d S r   r   r!   rs   rt   ru   s       r"   add_handlerzIOLoop.add_handler  	     	r%   c                     d S r   r   rw   s       r"   rx   zIOLoop.add_handler  ry   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.
        rb   rw   s       r"   rx   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.
        rb   )r!   rs   ru   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.
        rb   r!   rs   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.
        rb   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.
        rb   r    s    r"   stopzIOLoop.stop  s     "###r%   functimeoutc                 t    t           j        r(t          dt          t                   t
          d          }dddd fd}                     |           |2d fd}                                                      |z   |          } 	                                 | 
                    |           d         J d                                         sd                                         s)d	         rt          d
|z            t          d          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``.
        
FutureCell)futuretimeout_calledNFr   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_yieldedr   c                 ,                                     S r   )r   )r   r!   s    r"   <lambda>z.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"   runzIOLoop.run_sync.<locals>.run  s	   +%;;;;;;,_V44F V$$ +,2K)) ((C,/K)NN6****  9 9 9hh(+H%#C888889 x(444OOK13M3M3M3MNNNNNs   A >BBc                      d d<    d         J  d                                          s                                 d S d S )NTr   r   )cancelr   )r   r!   s   r"   timeout_callbackz)IOLoop.run_sync.<locals>.timeout_callback  sU    04,-
 #8,888"8,3355  IIKKKKK   r%   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   r>   r   )r!   r   r   r   r   r   timeout_handler   s   ``     @r"   run_synczIOLoop.run_sync  s   @  	"&)9TRR J "&??	O 	O 	O 	O 	O 	O 	O 	O* 	#	  	  	  	  	  	  	  "--diikkG.CEUVVN

///8$000x **,, 	RK4I4N4N4P4P 	R+, R"#IG#STTT ##PQQQ8$++---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)	r:   numbersRealcall_atdatetime	timedeltar   total_seconds	TypeError)r!   r   r   r   r6   s        r"   r   zIOLoop.add_timeout3  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   r6   s        r"   
call_laterzIOLoop.call_later\  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   r6   s        r"   r   zIOLoop.call_atk  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.
        rb   )r!   r   s     r"   r   zIOLoop.remove_timeout}  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.
        rb   r!   r   r   r6   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.
        rb   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)r:   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BadYieldErrorrR   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   )r:   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   )r:   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_task:  s    """""r%   c                 :    | j                             |           d S r   )r   discardr   s     r"   _unregister_taskzIOLoop._unregister_task=  s    ##A&&&&&r%   )r   r1   r(   )T)Fr   )Jr)   r*   r+   __doc__NONEREADWRITEERRORdictrV   setr   classmethodr   r@   staticmethodrE   rH   rK   r   overloadrD   r   r   rG   r`   rJ   re   rg   r   r
   rk   rn   rp   r'   r,   r   rx   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__)rB   s   @r"   r1   r1   H   s       K K\ DDEE $&& SUUN	*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. U.X U. U.3 U. U. U. U.n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%   r1   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   )	r:   r   r   r   r   r   next_timeout_counterr  )r!   r   r   r  s       r"   __init__z_Timeout.__init__G  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__W  s    ~//r%   c                 "    | j         |j         k    S r   r  r  s     r"   __le__z_Timeout.__le__Z  s    ~00r%   )r)   r*   r+   r   	__slots__r   r   r1   r  r   r  r  r   r%   r"   r  r  A  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 )Nr2   )millisecondsr   z4Periodic callback must have a positive callback_timeF)	r   r:   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)r1   rD   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     @@r2   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  ^  s       # #R 	 2x	223 X/67 	
 
   "   ! ! ! !D    
" 
" 
" 
"T T T T
4 44 4 4 4 4 4 4r%   r  )2r   rR   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   r   r   r   r   r   typing_extensionsr   r  r   r-   r.   r1   r  r  r   r%   r"   <module>r4     sv                				 



                               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	 111111111111*******H    (    WT]]WT%%%v' v' v' v' v'\ v' v' v'r1 1 1 1 1 1 1 1:|4 |4 |4 |4 |4 |4 |4 |4 |4 |4r%   