ó
L]c           @  s  d  Z  d d l m 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
 d d l m Z d d l Z d d l m Z d d	 l m Z e e d
 ƒ rÆ e j e j f Z n d Z d „  Z d e
 f d „  ƒ  YZ d e f d „  ƒ  YZ d S(   sj   This module wraps the :class:`Socket` and :class:`Context` found in :mod:`pyzmq <zmq>` to be non blocking
iÿÿÿÿ(   t   print_functionN(   t   Context(   t   Socketi   (   t   _Poller(   t   AsyncResult(   t   get_hubt   RCVTIMEOc         C  s2   y |  j  ƒ  Wn t k
 r- } |  j ƒ  n Xd S(   sN   simple wrapper for stopping an Event, allowing for method rename in gevent 1.0N(   t   stopt   AttributeErrort   cancel(   t   evtt   e(    (    s-   lib/python2.7/site-packages/zmq/green/core.pyt   _stop#   s    t   _Socketc           B  s×   e  Z d  Z e Z e Z d Z d Z d Z	 d Z
 e Z e Z d „  Z d „  Z d d „ Z d „  Z d „  Z d d d „ Z d „  Z d	 „  Z d
 e e d „ Z d
 e e d „ Z d „  Z d „  Z d „  Z d „  Z RS(   sO  Green version of :class:`zmq.Socket`

    The following methods are overridden:

        * send
        * recv

    To ensure that the ``zmq.NOBLOCK`` flag is set and that sending or receiving
    is deferred to the hub if a ``zmq.EAGAIN`` (retry) error is raised.
    
    The `__state_changed` method is triggered when the zmq.FD for the socket is
    marked as readable and triggers the necessary read and write events (which
    are waited for in the recv and send methods).

    Some double underscore prefixes are used to minimize pollution of
    :class:`zmq.Socket`'s namespace.
    g333333'@c         O  s9   t  t |  ƒ j | | Ž  t |  _ t |  _ |  j ƒ  d  S(   N(   t   superR   t   __init__t   Falset   _Socket__in_send_multipartt   _Socket__in_recv_multipartt   _Socket__setup_events(   t   selft   at   kw(    (    s-   lib/python2.7/site-packages/zmq/green/core.pyR   F   s    		c         C  s   |  j  ƒ  d  S(   N(   t   close(   R   (    (    s-   lib/python2.7/site-packages/zmq/green/core.pyt   __del__M   s    c         C  s$   t  t |  ƒ j | ƒ |  j ƒ  d  S(   N(   R   R   R   t   _Socket__cleanup_events(   R   t   linger(    (    s-   lib/python2.7/site-packages/zmq/green/core.pyR   P   s    c         C  sI   t  |  d d  ƒ r+ t |  j ƒ d  |  _ n  |  j j ƒ  |  j j ƒ  d  S(   Nt   _state_event(   t   getattrt   NoneR   R   t   _Socket__writablet   sett   _Socket__readable(   R   (    (    s-   lib/python2.7/site-packages/zmq/green/core.pyt   __cleanup_eventsT   s
    c         C  s¿   t  ƒ  |  _ t  ƒ  |  _ |  j j ƒ  |  j j ƒ  y> t ƒ  j j |  j t j	 ƒ d ƒ |  _
 |  j
 j |  j ƒ WnH t k
 rº d d l m } | |  j t j	 ƒ |  j d t ƒ|  _
 n Xd  S(   Ni   iÿÿÿÿ(   t
   read_eventt   persist(   R   R    R   R   R   t   loopt   iot
   getsockoptt   zmqt   FDR   t   startt   _Socket__state_changedR   t   gevent.coreR"   t   True(   R   R"   (    (    s-   lib/python2.7/site-packages/zmq/green/core.pyt   __setup_events]   s    'c         C  s­   |  j  r |  j ƒ  d  Sy t t |  ƒ j t j ƒ } Wn6 t j k
 rn } |  j j	 | ƒ |  j
 j	 | ƒ n; X| t j @rŒ |  j j ƒ  n  | t j @r© |  j
 j ƒ  n  d  S(   N(   t   closedR   R   R   R&   R'   t   EVENTSt   ZMQErrorR   t   set_exceptionR    t   POLLOUTR   t   POLLIN(   R   t   eventt   _evtypet   eventst   exc(    (    s-   lib/python2.7/site-packages/zmq/green/core.pyt   __state_changedk   s    	
c         C  s?  |  j  j ƒ  s t d ƒ ‚ t ƒ  |  _  t j ƒ  } |  j } | rW t j d | ƒ } n d  } zº y* | rv | j	 ƒ  n  |  j  j
 d t ƒ Wn‰ t j k
 r} | | k	 r± ‚  n  t j ƒ  } |  j r| r| | | k r|  j t j ƒ t j @rt d |  j d t j ƒqn XWd  | r-| j ƒ  n  |  j  j ƒ  Xd  S(   Ns.   Only one greenlet can be waiting on this eventt   secondst   blocks6   BUG: gevent may have missed a libzmq send event on %i!t   file(   R   t   readyt   AssertionErrorR   t   timet   _gevent_bug_timeoutt   geventt   TimeoutR   R)   t   getR,   t   _debug_geventR&   R'   R/   R2   t   printR(   t   syst   stderrR	   R   (   R   t   tict   dtt   timeoutt   tt   toc(    (    s-   lib/python2.7/site-packages/zmq/green/core.pyt   _wait_write{   s,    	 %c         C  s?  |  j  j ƒ  s t d ƒ ‚ t ƒ  |  _  t j ƒ  } |  j } | rW t j d | ƒ } n d  } zº y* | rv | j	 ƒ  n  |  j  j
 d t ƒ Wn‰ t j k
 r} | | k	 r± ‚  n  t j ƒ  } |  j r| r| | | k r|  j t j ƒ t j @rt d |  j d t j ƒqn XWd  | r-| j ƒ  n  |  j  j ƒ  Xd  S(   Ns.   Only one greenlet can be waiting on this eventR9   R:   s6   BUG: gevent may have missed a libzmq recv event on %i!R;   (   R    R<   R=   R   R>   R?   R@   RA   R   R)   RB   R,   RC   R&   R'   R/   R3   RD   R(   RE   RF   R	   R   (   R   RG   RH   RI   RJ   RK   (    (    s-   lib/python2.7/site-packages/zmq/green/core.pyt
   _wait_read˜   s,    	 %i    c         K  s  | t  j @rS z( t t |  ƒ j | | | | |  } Wd |  j sN |  j ƒ  n  X| S| t  j O} xš t rü y% t t |  ƒ j | | | | ƒ } WnD t  j k
 rÔ } | j	 t  j
 k rï |  j sË |  j ƒ  n  ‚  qï n X|  j së |  j ƒ  n  | S|  j ƒ  qc Wd S(   s£   send, which will only block current greenlet
        
        state_changed always fires exactly once (success or fail) at the
        end of this method.
        N(   R'   t   NOBLOCKR   R   t   sendR   R*   R,   R0   t   errnot   EAGAINRL   (   R   t   datat   flagst   copyt   trackt   kwargst   msgR   (    (    s-   lib/python2.7/site-packages/zmq/green/core.pyRO   ·   s&    (		%	
	c         C  sø   | t  j @rM z" t t |  ƒ j | | | ƒ } Wd |  j sH |  j ƒ  n  X| S| t  j O} x— t ró y" t t |  ƒ j | | | ƒ } WnD t  j k
 rË } | j	 t  j
 k ræ |  j sÂ |  j ƒ  n  ‚  qæ n X|  j sâ |  j ƒ  n  | S|  j ƒ  q] Wd S(   s£   recv, which will only block current greenlet
        
        state_changed always fires exactly once (success or fail) at the
        end of this method.
        N(   R'   RN   R   R   t   recvR   R*   R,   R0   RP   RQ   RM   (   R   RS   RT   RU   RW   R   (    (    s-   lib/python2.7/site-packages/zmq/green/core.pyRX   Ù   s&    "		"	
	c         O  sC   t  |  _ z t t |  ƒ j | | Ž  } Wd t |  _ |  j ƒ  X| S(   sA   wrap send_multipart to prevent state_changed on each partial sendN(   R,   R   R   R   t   send_multipartR   R*   (   R   t   argsRV   RW   (    (    s-   lib/python2.7/site-packages/zmq/green/core.pyRY   ö   s    		c         O  sC   t  |  _ z t t |  ƒ j | | Ž  } Wd t |  _ |  j ƒ  X| S(   sA   wrap recv_multipart to prevent state_changed on each partial recvN(   R,   R   R   R   t   recv_multipartR   R*   (   R   RZ   RV   RW   (    (    s-   lib/python2.7/site-packages/zmq/green/core.pyR[      s    		c         C  sW   | t  k r t j d t ƒ n  t t |  ƒ j | ƒ } | t j k rS |  j	 ƒ  n  | S(   s+   trigger state_changed on getsockopt(EVENTS)s0   TIMEO socket options have no effect in zmq.green(
   t   TIMEOSt   warningst   warnt   UserWarningR   R   RB   R'   R/   R*   (   R   t   optt   optval(    (    s-   lib/python2.7/site-packages/zmq/green/core.pyRB   
  s    c         C  s8   | t  k r t j d t ƒ n  t t |  ƒ j | | ƒ S(   s   set socket options0   TIMEO socket options have no effect in zmq.green(   R\   R]   R^   R_   R   R   R   (   R   R`   t   val(    (    s-   lib/python2.7/site-packages/zmq/green/core.pyR     s    N(   t   __name__t
   __module__t   __doc__R   R   R   R   R   R    R   R?   RC   R   t   _poller_classR   R   R   R   R   R*   RL   RM   R,   RO   RX   RY   R[   RB   R   (    (    (    s-   lib/python2.7/site-packages/zmq/green/core.pyR   +   s.   							"	
	
		t   _Contextc           B  s   e  Z d  Z e Z RS(   sr   Replacement for :class:`zmq.Context`

    Ensures that the greened Socket above is used in calls to `socket`.
    (   Rc   Rd   Re   R   t   _socket_class(    (    (    s-   lib/python2.7/site-packages/zmq/green/core.pyRg     s   (    (   Re   t
   __future__R    RE   R>   R]   R'   R   t   _original_ContextR   t   _original_Sockett   pollR   R@   t   gevent.eventR   t
   gevent.hubR   t   hasattrR   t   SNDTIMEOR\   R   R   Rg   (    (    (    s-   lib/python2.7/site-packages/zmq/green/core.pyt   <module>   s"   	ï