
H/\c        
   @@ sn  d  Z  d d l m Z m Z d d l m Z d d l Z d d l Z d d l	 m	 Z
 d d l	 m Z d d l	 m Z d d	 d
 d d d d d d d g
 Z d d l m Z d d l m Z d d l m Z d d l m Z d d l m Z d d l m Z d d l m Z d d l m Z d d l m Z d d l m Z d d l m Z d d l m  Z! d d l m" Z" d d l# m$ Z$ d d  l% m& Z& d d! l' m( Z( e( j) Z* e( j+ Z, d d" l- m. Z. d d# l/ m0 Z0 e1 e  j2 Z3 e3   Z4 d$   Z5 d e6 d%  Z7 d d&  Z8 e d'  Z9 d e: f d(     YZ; e< d)  Z= d e& f d*     YZ> e" e>  d+ e: f d,     YZ? d S(-   s   
Event-loop hub.
i    (   t   absolute_importt   print_function(   t   partialN(   t   greenlet(   t
   getcurrent(   t   GreenletExitR   R   t	   spawn_rawt   sleept   killt   signalt   reinitt   get_hubt   Hubt   Waiter(   t   config(   t   thread_mod_name(   t   readproperty(   t   Lazy(   t   gmctime(   t   IdentRegistry(   R   (   t   get_loop(   t   set_hub(   t   set_loop(   t   get_hub_if_exists(   t   get_hub_noargs(   t   set_default_hub_class(   t   TrackedRawGreenlet(   t   WaitOperationsGreenlet(   t   _hub_primitives(   t   LoopExit(   R   c         O@ s   t  |   s t d   n  t   } t j r3 t n t } | rv t |  | |  }  | |  |  } | j j	 | j
  n% | |  |  } | j j	 | j
 |  | S(   sG  
    Create a new :class:`greenlet.greenlet` object and schedule it to
    run ``function(*args, **kwargs)``.

    This returns a raw :class:`~greenlet.greenlet` which does not have all the useful
    methods that :class:`gevent.Greenlet` has. Typically, applications
    should prefer :func:`~gevent.spawn`, but this method may
    occasionally be useful as an optimization if there are many
    greenlets involved.

    .. versionchanged:: 1.1a3
        Verify that ``function`` is callable, raising a TypeError if not. Previously,
        the spawned greenlet would have failed the first time it was switched to.

    .. versionchanged:: 1.1b1
       If *function* is not callable, immediately raise a :exc:`TypeError`
       instead of spawning a greenlet that will raise an uncaught TypeError.

    .. versionchanged:: 1.1rc2
        Accept keyword arguments for ``function`` as previously (incorrectly)
        documented. Note that this may incur an additional expense.

    .. versionchanged:: 1.3a2
       Populate the ``spawning_greenlet`` and ``spawn_tree_locals``
       attributes of the returned greenlet.

    .. versionchanged:: 1.3b1
       *Only* populate ``spawning_greenlet`` and ``spawn_tree_locals``
       if ``GEVENT_TRACK_GREENLET_TREE`` is enabled (the default). If not enabled,
       those attributes will not be set.

    s   function must be callable(   t   callablet	   TypeErrort   _get_hub_noargst   GEVENT_CONFIGt   track_greenlet_treeR   t   RawGreenlett   _functools_partialt   loopt   run_callbackt   switch(   t   functiont   argst   kwargst   hubt   factoryt   g(    (    s)   lib/python2.7/site-packages/gevent/hub.pyR   C   s    !	c         C@ s   t    } | j } |  d k rJ t |  } | j | j d  | j   n5 | j |  d |  } | j   | j	 |  Wd QXd S(   s  
    Put the current greenlet to sleep for at least *seconds*.

    *seconds* may be specified as an integer, or a float if fractional
    seconds are desired.

    .. tip:: In the current implementation, a value of 0 (the default)
       means to yield execution to any other runnable greenlets, but
       this greenlet may be scheduled again before the event loop
       cycles (in an extreme case, a greenlet that repeatedly sleeps
       with 0 can prevent greenlets that are ready to do I/O from
       being scheduled for some (small) period of time); a value greater than
       0, on the other hand, will delay running this greenlet until
       the next iteration of the loop.

    If *ref* is False, the greenlet running ``sleep()`` will not prevent :func:`gevent.wait`
    from exiting.

    .. versionchanged:: 1.3a1
       Sleeping with a value of 0 will now be bounded to approximately block the
       loop for no longer than :func:`gevent.getswitchinterval`.

    .. seealso:: :func:`idle`
    i    t   refN(
   R    R%   R   R&   R'   t   Nonet   gett   timert
   update_nowt   wait(   t   secondsR.   R+   R%   t   waitert   t(    (    s)   lib/python2.7/site-packages/gevent/hub.pyR   z   s    		
c         C@ s;   t    } | j j   } |  r* |  | _ n  | j |  d S(   sO  
    Cause the calling greenlet to wait until the event loop is idle.

    Idle is defined as having no other events of the same or higher
    *priority* pending. That is, as long as sockets, timeouts or even
    signals of the same or higher priority are being processed, the loop
    is not idle.

    .. seealso:: :func:`sleep`
    N(   R    R%   t   idlet   priorityR3   (   R8   R+   t   watcher(    (    s)   lib/python2.7/site-packages/gevent/hub.pyR7      s
    	c         C@ sQ   |  j  sM t |  d  r1 |  j d | d t  qM t   j j |  j |  n  d S(   s%  
    Kill greenlet asynchronously. The current greenlet is not unscheduled.

    .. note::

        The method :meth:`Greenlet.kill` method does the same and
        more (and the same caveats listed there apply here). However, the MAIN
        greenlet - the one that exists initially - does not have a
        ``kill()`` method, and neither do any created with :func:`spawn_raw`,
        so you have to use this function.

    .. caution:: Use care when killing greenlets. If they are not prepared for
       exceptions, this could result in corrupted state.

    .. versionchanged:: 1.1a2
        If the ``greenlet`` has a :meth:`kill <Greenlet.kill>` method, calls it. This prevents a
        greenlet from being switched to for the first time after it's been
        killed but not yet executed.
    R   t	   exceptiont   blockN(   t   deadt   hasattrR   t   FalseR    R%   R&   t   throw(   R   R:   (    (    s)   lib/python2.7/site-packages/gevent/hub.pyR      s    	c           B@ s_   e  Z d  Z d Z d   Z d   Z d   Z e e e  Z	 [ [ d   Z
 d   Z d   Z RS(   s_  
    Call the *handler* with the *args* and *kwargs* when the process
    receives the signal *signalnum*.

    The *handler* will be run in a new greenlet when the signal is delivered.

    This returns an object with the useful method ``cancel``, which, when called,
    will prevent future deliveries of *signalnum* from calling *handler*.

    .. note::

        This may not operate correctly with SIGCHLD if libev child watchers
        are used (as they are by default with os.fork).

    .. versionchanged:: 1.2a1
       The ``handler`` argument is required to be callable at construction time.
    c         O@ s   t  |  s t d   n  t   |  _ |  j j j | d t |  _ |  j j |  j	  | |  _
 | |  _ | |  _ |  j d  k r d d l m } | |  _ n  d  S(   Ns    signal handler must be callable.R.   i    (   t   Greenlet(   R   R   R    R+   R%   R	   R>   R9   t   startt   _startt   handlerR)   R*   t   greenlet_classR/   t   geventR@   (   t   selft	   signalnumRC   R)   R*   R@   (    (    s)   lib/python2.7/site-packages/gevent/hub.pyt   __init__   s    			c         C@ s
   |  j  j S(   N(   R9   R.   (   RF   (    (    s)   lib/python2.7/site-packages/gevent/hub.pyt   _get_ref   s    c         C@ s   | |  j  _ d  S(   N(   R9   R.   (   RF   t   value(    (    s)   lib/python2.7/site-packages/gevent/hub.pyt   _set_ref   s    c         C@ s   |  j  j   d  S(   N(   R9   t   stop(   RF   (    (    s)   lib/python2.7/site-packages/gevent/hub.pyt   cancel  s    c         C@ sG   y  |  j  |  j  } | j   Wn  |  j j d  t j    n Xd  S(   N(   RD   t   handleR'   R+   t   handle_errorR/   t   syst	   _exc_info(   RF   R   (    (    s)   lib/python2.7/site-packages/gevent/hub.pyRB     s
    c         C@ sA   y |  j  |  j |  j   Wn  |  j j d  t j    n Xd  S(   N(   RC   R)   R*   R+   RO   R/   RP   t   exc_info(   RF   (    (    s)   lib/python2.7/site-packages/gevent/hub.pyRN     s    N(   t   __name__t
   __module__t   __doc__R/   RD   RH   RI   RK   t   propertyR.   RM   RB   RN   (    (    (    s)   lib/python2.7/site-packages/gevent/hub.pyR	      s   					c         C@ su   |  d k r t   n |  }  |  d k r+ d S|  j j   x6 |  j |  j |  j f D] } t | d d      qQ Wd S(   s  
    reinit() -> None

    Prepare the gevent hub to run in a new (forked) process.

    This should be called *immediately* after :func:`os.fork` in the
    child process. This is done automatically by
    :func:`gevent.os.fork` or if the :mod:`os` module has been
    monkey-patched. If this function is not called in a forked
    process, symptoms may include hanging of functions like
    :func:`socket.getaddrinfo`, and the hub's threadpool is unlikely
    to work.

    .. note:: Registered fork watchers may or may not run before
       this function (and thus ``gevent.os.fork``) return. If they have
       not run, they will run "soon", after an iteration of the event loop.
       You can force this by inserting a few small (but non-zero) calls to :func:`sleep`
       after fork returns. (As of gevent 1.1 and before, fork watchers will
       not have run, but this may change in the future.)

    .. note:: This function may be removed in a future major release
       if the fork process can be more smoothly managed.

    .. warning:: See remarks in :func:`gevent.os.fork` about greenlets
       and event loop watchers in the child process.
    Nt   _on_forkc           S@ s   d  S(   N(   R/   (    (    (    s)   lib/python2.7/site-packages/gevent/hub.pyt   <lambda>J  s    (   R/   t   _get_hubR%   R
   t   _threadpoolt	   _resolvert   periodic_monitoring_threadt   getattr(   R+   t   obj(    (    s)   lib/python2.7/site-packages/gevent/hub.pyR
     s    c           B@ sm  e  Z d  Z e e e f Z e e f Z d Z	 d Z d Z d Z d Z d d d  Z e d    Z e d    Z e d    Z e d    Z d	   Z d
   Z d   Z e d    Z d   Z d   Z d   Z d d  Z d d  Z e d    Z  d   Z! d   Z" d   Z# e e! e" e# d  Z$ e d    Z% d   Z& d   Z' d   Z( e e& e' e( d  Z) RS(   s  
    A greenlet that runs the event loop.

    It is created automatically by :func:`get_hub`.

    .. rubric:: Switching

    Every time this greenlet (i.e., the event loop) is switched *to*,
    if the current greenlet has a ``switch_out`` method, it will be
    called. This allows a greenlet to take some cleanup actions before
    yielding control. This method should not call any gevent blocking
    functions.
    i
   t    i    c         C@ s  t  j |  d  d   t   |  _ t | d  rU | d  k	 rI t d   n  | |  _ nu t   d  k	 rs t   |  _ nW | d  k r |  j t	 k r t
 } n  | d  k r |  j } n  |  j d | d |  |  _ d  |  _ d  |  _ t j |  _ t j d 7_ t j |  _ d  S(   Nt   runs   Unexpected argument: defaultt   flagst   defaulti   (   R   RH   R/   t   get_thread_identt   thread_identR=   R   R%   R   t   MAIN_THREAD_IDENTR>   t   backendt
   loop_classR[   RZ   R!   t   format_contextR   t   _hub_countert   minimal_ident(   RF   R%   Rb   (    (    s)   lib/python2.7/site-packages/gevent/hub.pyRH     s$    			c         C@ s   t    S(   N(   R   (   RF   (    (    s)   lib/python2.7/site-packages/gevent/hub.pyt   ident_registry  s    c         C@ s   t  j S(   N(   R!   R%   (   RF   (    (    s)   lib/python2.7/site-packages/gevent/hub.pyRg     s    c         C@ s   t  j S(   N(   R!   t   libev_backend(   RF   (    (    s)   lib/python2.7/site-packages/gevent/hub.pyRf     s    c         C@ s   |  j  t k S(   sW   
        Is this the hub for the main thread?

        .. versionadded:: 1.3b1
        (   Rd   Re   (   RF   (    (    s)   lib/python2.7/site-packages/gevent/hub.pyt   main_hub  s    c         C@ s   |  j  d  k r d } nG y |  j  j   } Wn1 t k
 r^ } t |  pX t |  pX d } n Xd |  j j |  j t	 |   | f } |  j
 d  k	 r | d |  j
 7} n  |  j d  k	 r | d |  j 7} n  | d t |  j  f 7} | d S(   Nt	   destroyedt   errors   <%s %r at 0x%x %ss    resolver=%rs    threadpool=%rs    thread_ident=%st   >(   R%   R/   t   _formatt	   Exceptiont   strt   reprt	   __class__RS   t   namet   idR[   RZ   t   hexRd   (   RF   t   infot   ext   result(    (    s)   lib/python2.7/site-packages/gevent/hub.pyt   __repr__  s"    	"		
c         C@ s~   t  | t  r | |  } n  t | |  j  sI |  j | | | |  n  | d k sg t | |  j  rz |  j | |  n  d S(   sY  
        Called by the event loop when an error occurs. The arguments
        type, value, and tb are the standard tuple returned by :func:`sys.exc_info`.

        Applications can set a property on the hub with this same signature
        to override the error handling provided by this class.

        Errors that are :attr:`system errors <SYSTEM_ERROR>` are passed
        to :meth:`handle_system_error`.

        :param context: If this is ``None``, indicates a system error that
            should generally result in exiting the loop and being thrown to the
            parent greenlet.
        N(   t
   isinstanceRs   t
   issubclasst	   NOT_ERRORt   print_exceptionR/   t   SYSTEM_ERRORt   handle_system_error(   RF   t   contextt   typeRJ   t   tb(    (    s)   lib/python2.7/site-packages/gevent/hub.pyRO     s    c         C@ s   t    } | |  k s3 | |  j k s3 |  j d k rI |  j j | |  np d } y |  j j | j  } Wn t j d |  j	  n Xz |  j j | |  Wd | d k	 r | j
   n  Xd S(   s   
        Called from `handle_error` when the exception type is determined
        to be a :attr:`system error <SYSTEM_ERROR>`.

        System errors cause the exception to be raised in the main
        greenlet (the parent of this hub).
        t   fileN(   R   t   parentR%   R/   R?   R&   R'   t	   tracebackt	   print_exct   exception_streamRL   (   RF   R   RJ   t   currentt   cb(    (    s)   lib/python2.7/site-packages/gevent/hub.pyR     s    	*c         C@ s:   t  r t  j n d } t |  j d k r6 | j } n  | S(   s   
        The stream to which exceptions will be written.
        Defaults to ``sys.stderr`` unless assigned to.

        .. versionadded:: 1.2a1
        t   FileObjectThreadN(   RP   t   stderrR/   R   RS   t   io(   RF   R   (    (    s)   lib/python2.7/site-packages/gevent/hub.pyR      s    c         C@ s  |  j  } | s d  S| d  k r6 | j d | j  n t j | | | d | ~ y3 | j t    | j | d  k	 r} d n d  Wn n X| d  k	 rt | t  s y |  j	 |  } Wq t j
 d |  j   t |  } q Xn  | j d | t | d d  f  n  d  S(   Ns   %s
R   t    s   
s   %s failed with %s

RS   R:   (   R   R/   t   writeRS   R   R   R   R}   Rs   Rh   R   Rt   R]   (   RF   R   R   RJ   R   t	   errstream(    (    s)   lib/python2.7/site-packages/gevent/hub.pyR     s(    	#c         C@ s   |  t    k s t d   |  j   xq |  j } |  | _ z | j   Wd d | _ Xg  } t | d  ry | j   } n  |  j	 j
 t d |  |   q( Wd S(   s  
        Entry-point to running the loop. This method is called automatically
        when the hub greenlet is scheduled; do not call it directly.

        :raises gevent.exceptions.LoopExit: If the loop finishes running. This means
           that there are no other scheduled greenlets, and no active
           watchers or servers. In some situations, this indicates a
           programming error.
        s   Do not call Hub.run() directlyNt   debugs"   This operation would block forever(   R   t   AssertionErrort    start_periodic_monitoring_threadR%   t   error_handlerR`   R/   R=   R   R   R?   R   (   RF   R%   R   (    (    s)   lib/python2.7/site-packages/gevent/hub.pyR`   6  s    

		
c         C@ s   |  j  d  k r t j r d d l m } d d l m } d d l m } | |   |  _  |  j	 rp |  j  j
   n  | | |  j    n  |  j  S(   Ni    (   t   PeriodicMonitoringThread(   t!   PeriodicMonitorThreadStartedEvent(   t   notify_and_call_entry_points(   R\   R/   R!   t   monitor_threadt   gevent._monitorR   t   gevent.eventsR   R   Rm   t   install_monitor_memory_usage(   RF   R   R   R   (    (    s)   lib/python2.7/site-packages/gevent/hub.pyR   R  s    	c         C@ s   t    |  j k s t d   |  j r+ t St |   } | d k	 rq |  j j | d t	 } | j
 | j d  n  z' y | j   Wn t k
 r t SXWd | d k	 r | j   | j   n  Xt	 S(   sn  Wait for the event loop to finish. Exits only when there are
        no more spawned greenlets, started servers, active timeouts or watchers.

        If *timeout* is provided, wait no longer for the specified number of seconds.

        Returns True if exited because the loop finished execution.
        Returns False if exited because of timeout expired.
        s$   only possible from the MAIN greenletR.   N(   R   R   R   R<   t   TrueR   R/   R%   R1   R>   RA   R'   R0   R   RL   t   close(   RF   t   timeoutR5   (    (    s)   lib/python2.7/site-packages/gevent/hub.pyt   joinf  s     			
c         C@ s   |  j  d k	 r( |  j  j   d |  _  n  |  j d k	 rM |  j j   |  ` n  |  j d k	 rr |  j j   |  ` n  | d k r |  j j } n  | r t   |  j k r t	 d  n  |  j j
   n t	 |  j  d |  _ t   |  k r t d  n  d S(   s   
        Destroy this hub and clean up its resources.

        If you manually create hubs, you *should* call this
        method before disposing of the hub object reference.
        N(   R\   R/   R   R[   R   RZ   R%   Rb   R   R   t   destroyRY   R   (   RF   t   destroy_loop(    (    s)   lib/python2.7/site-packages/gevent/hub.pyR     s&    			c         C@ s   t  j S(   N(   R!   t   resolver(   RF   (    (    s)   lib/python2.7/site-packages/gevent/hub.pyt   resolver_class  s    c         C@ s.   |  j  d  k r' |  j d |   |  _  n  |  j  S(   NR+   (   R[   R/   R   (   RF   (    (    s)   lib/python2.7/site-packages/gevent/hub.pyt   _get_resolver  s    c         C@ s   | |  _  d  S(   N(   R[   (   RF   RJ   (    (    s)   lib/python2.7/site-packages/gevent/hub.pyt   _set_resolver  s    c         C@ s   d  |  _ d  S(   N(   R/   R[   (   RF   (    (    s)   lib/python2.7/site-packages/gevent/hub.pyt   _del_resolver  s    s   
                        The DNS resolver that the socket functions will use.

                        .. seealso:: :doc:`/dns`
                        c         C@ s   t  j S(   N(   R!   t
   threadpool(   RF   (    (    s)   lib/python2.7/site-packages/gevent/hub.pyt   threadpool_class  s    c         C@ s4   |  j  d  k r- |  j |  j d |  |  _  n  |  j  S(   NR+   (   RZ   R/   R   t   threadpool_size(   RF   (    (    s)   lib/python2.7/site-packages/gevent/hub.pyt   _get_threadpool  s    c         C@ s   | |  _  d  S(   N(   RZ   (   RF   RJ   (    (    s)   lib/python2.7/site-packages/gevent/hub.pyt   _set_threadpool  s    c         C@ s   d  |  _ d  S(   N(   R/   RZ   (   RF   (    (    s)   lib/python2.7/site-packages/gevent/hub.pyt   _del_threadpool  s    s  
                          The threadpool associated with this hub.

                          Usually this is a
                          :class:`gevent.threadpool.ThreadPool`, but
                          you :attr:`can customize that
                          <gevent._config.Config.threadpool>`.

                          Use this object to schedule blocking
                          (non-cooperative) operations in a different
                          thread to prevent them from halting the event loop.
                          N(*   RS   RT   RU   t   KeyboardInterruptt
   SystemExitt   SystemErrorR   R   R   R   R/   R\   Rd   Rv   Ri   RH   R   Rk   RV   Rg   Rf   Rm   R|   RO   R   R   R   R   R`   R   R   R   R   R   R   R   R   R   R   R   R   R   (    (    (    s)   lib/python2.7/site-packages/gevent/hub.pyR   V  sD   					$		$							t	   linkproxyc           B@ s&   e  Z d  d g Z d   Z d   Z RS(   t   callbackR^   c         C@ s   | |  _  | |  _ d  S(   N(   R   R^   (   RF   R   R^   (    (    s)   lib/python2.7/site-packages/gevent/hub.pyRH     s    	c         G@ s2   |  j  } |  j } d  |  _  d  |  _ | |  d  S(   N(   R   R^   R/   (   RF   R)   R   R^   (    (    s)   lib/python2.7/site-packages/gevent/hub.pyt   __call__  s
    				(   RS   RT   t	   __slots__RH   R   (    (    (    s)   lib/python2.7/site-packages/gevent/hub.pyR     s   	(@   RU   t
   __future__R    R   t	   functoolsR   R$   RP   R   R   R#   R   R   t   __all__t   gevent._configR   R!   t   gevent._compatR   t   gevent._utilR   R   R   t   gevent._identR   t   gevent._hub_localR   R   R   R   R   RY   R   R    R   t   gevent._greenlet_primitivesR   t   gevent._hub_primitivesR   RE   R   t   wait_on_objectsR3   t   iwait_on_objectst   iwaitt   gevent.exceptionsR   t   gevent._waiterR   t
   __import__t	   get_identRc   Re   R   R   R   R7   R   t   objectR	   R/   R
   R   R   (    (    (    s)   lib/python2.7/site-packages/gevent/hub.pyt   <module>   sb   					7(@D 
