U
    @fbF                     @   s(  d Z edZddlZddlmZ ddlmZ	 ddgZ
eee e
d dd	lmZ z eed
s`eZeedsneZW n ek
r   Y nX G dd deZG dd dZG dd dZG dd dejZdd ZejZejZejZej Z!ej"Z#ej$Z%ej&Z'ej(Z)ej*Z+ej,Z-ej.Z/ej0Z1G dd deZdS )zuThe :mod:`zmq` module wraps the :class:`Socket` and :class:`Context`
found in :mod:`pyzmq <zmq>` to be non blocking.
Zzmq    N)slurp_properties)	greenletsContextSocket)ignore)dequeXREQXREPc                   @   s   e Zd ZdS )LockReleaseErrorN)__name__
__module____qualname__ r   r   L/var/www/html/chatgpt/venv/lib/python3.8/site-packages/eventlet/green/zmq.pyr
      s   r
   c                   @   sD   e Zd ZdZdd Zdd ZeZdd Zdd	 Zd
d Z	dd Z
dS )
_QueueLocka  A Lock that can be acquired by at most one thread. Any other
    thread calling acquire will be blocked in a queue. When release
    is called, the threads are awoken in the order they blocked,
    one at a time. This lock can be required recursively by the same
    thread.c                 C   s$   t  | _d| _d | _tj | _d S )Nr   )r   _waiters_count_holdereventlethubsget_hub_hubselfr   r   r   __init__#   s    z_QueueLock.__init__c                 C   s
   t | jS N)boolr   r   r   r   r   __nonzero__)   s    z_QueueLock.__nonzero__c                 C   s   |    d S r   )acquirer   r   r   r   	__enter__.   s    z_QueueLock.__enter__c                 C   s   |    d S r   )release)r   typevalue	tracebackr   r   r   __exit__1   s    z_QueueLock.__exit__c                 C   s|   t  }| js| jdkrd| j|k	rd| j| | j  | j }||ksRt	d| jdksdt	d|| _|  jd7  _d S )Nr   z"Waiting threads woken out of orderz2After waking a thread, the lock must be unacquired   )
greenlet
getcurrentr   r   r   appendr   switchpopleftAssertionError)r   currentwr   r   r   r   4   s    

z_QueueLock.acquirec                 C   sP   | j dkrtd|  j d8  _ | j dkrLd | _| jrL| jd| jd j d S )Nr   zCannot release unacquired lockr%   )r   r
   r   r   r   schedule_call_globalr)   r   r   r   r   r    B   s    

z_QueueLock.releaseN)r   r   r   __doc__r   r   __bool__r   r$   r   r    r   r   r   r   r      s   r   c                   @   s6   e Zd ZdZdd Zdd ZeZdddZd	d
 ZdS )_BlockedThreadzIs either empty, or represents a single blocked thread that
    blocked itself by calling the block() method. The thread can be
    awoken by calling wake(). Wake() can be called multiple times and
    all but the first call will have no effect.c                 C   s   d | _ d | _tj | _d S r   )_blocked_thread
_wakeupperr   r   r   r   r   r   r   r   r   T   s    z_BlockedThread.__init__c                 C   s
   | j d k	S r   )r2   r   r   r   r   r   Y   s    z_BlockedThread.__nonzero__Nc                 C   st   | j d k	rtdt | _ |d k	r>| j|| j  | j z| j
  W 5 d | _ | jd k	rn| j	  d | _X d S )Nz6Cannot block more than one thread on one BlockedThread)r2   	Exceptionr&   r'   r   Zschedule_call_localclockwaker3   cancelr)   )r   deadliner   r   r   block^   s    



z_BlockedThread.blockc                 C   s0   | j dk	r,| jdkr,| jd| j j| _dS dS )zSchedules the blocked thread to be awoken and return
        True. If wake has already been called or if there is no
        blocked thread, then this call has no effect and returns
        False.Nr   TF)r2   r3   r   r.   r)   r   r   r   r   r6   q   s    z_BlockedThread.wake)N)	r   r   r   r/   r   r   r0   r9   r6   r   r   r   r   r1   N   s   
r1   c                   @   s   e Zd ZdZdd ZdS )r   z%Subclass of :class:`zmq.Context`
    c                 C   s   | j rttt| |S )a  Overridden method to ensure that the green version of socket is used

        Behaves the same as :meth:`zmq.Context.socket`, but ensures
        that a :class:`Socket` with all of its send and recv methods set to be
        non-blocking is returned
        )closedZMQErrorENOTSUPr   )r   socket_typer   r   r   socket   s    zContext.socketN)r   r   r   r/   r>   r   r   r   r   r   |   s   c                    s    fdd}|S )zQA decorator that copies the __name__ and __doc__ from the given
    function
    c                    s    j | _  j| _| S r   )r   r/   )Zdest_fn	source_fnr   r   wrapper   s    z_wraps.<locals>.wrapperr   )r@   rA   r   r?   r   _wraps   s    rB   c                       s  e Zd ZdZ fddZeejd" fdd	Zeejdd Zeej	d#ddZ	eej
d$ddZ
eejd%ddZeejd&ddZeejd'ddZeejd(ddZeejd)ddZeejd*ddZeejd+ddZeejd,d d!Z  ZS )-r   a  Green version of :class:``zmq.core.socket.Socket``.

    The following three methods are always overridden:
        * send
        * recv
        * getsockopt
    To ensure that the ``zmq.NOBLOCK`` flag is set and that sending or receiving
    is deferred to the hub (using :func:``eventlet.hubs.trampoline``) if a
    ``zmq.EAGAIN`` (retry) error is raised.

    For some socket types, the following methods are also overridden:
        * send_multipart
        * recv_multipart
    c                    s   t  || t  jd< t  jd< t  jd< t  jd<  fdd}tj }||j	 
t|dd d	d  jd
< |j jd< d S )N_eventlet_send_event_eventlet_recv_event_eventlet_send_lock_eventlet_recv_lockc                    s*    j  } j }|s&|s&t t d S r   )rC   r6   rD   _Socket_getsockoptEVENTS)fdZ	send_wakeZ	recv_waker   r   r   event   s    

zSocket.__init__.<locals>.eventc                 S   s   d S r   r   )_r   r   r   <lambda>       z!Socket.__init__.<locals>.<lambda>c                   S   s   d S r   r   r   r   r   r   rL      rM   _eventlet_listener_eventlet_clock)superr   r1   __dict__r   r   r   r   addREAD
getsockoptZFDr5   )r   contextr=   rJ   Zhub	__class__r   r   r      s    

zSocket.__init__Nc                    sJ   t  | | jd k	rFtj | j d | jd< | j	  | j
	  d S )NrN   )rP   closerN   r   r   r   removerQ   rC   r6   rD   )r   ZlingerrV   r   r   rX      s    


zSocket.closec                 C   s:   t | |}|tkr6|t@ r$| j  |t@ r6| j  |S r   )rG   rH   POLLOUTrC   r6   POLLINrD   )r   optionresultr   r   r   rT     s    


zSocket.getsockoptr   TFc                 C   s   |t @ r0t| ||||}| j  | j  |S |t O }| jx zbz"t| ||||W W LW  5 Q R  S  tk
r } z|jtkr| j	  n W 5 d}~X Y nX W 5 | j  X q@W 5 Q R X dS )zA send method that's safe to use when multiple greenthreads
        are calling send, send_multipart, recv and recv_multipart on
        the same socket.
        N)
NOBLOCK_Socket_sendrC   r6   rD   rE   r;   errnoEAGAINr9   )r   msgflagscopytrackr]   er   r   r   send  s    

"
zSocket.sendc              
   C   sF   |t @ rt| ||||S | j t| ||||W  5 Q R  S Q R X dS )zA send_multipart method that's safe to use when multiple
        greenthreads are calling send, send_multipart, recv and
        recv_multipart on the same socket.
        N)r^   _Socket_send_multipartrE   )r   Z	msg_partsrc   rd   re   r   r   r   send_multipart5  s    zSocket.send_multipartutf-8c              
   C   sF   |t @ rt| ||||S | j t| ||||W  5 Q R  S Q R X dS )zA send_string method that's safe to use when multiple
        greenthreads are calling send, send_string, recv and
        recv_string on the same socket.
        N)r^   _Socket_send_stringrE   )r   urc   rd   encodingr   r   r   send_stringC  s    zSocket.send_string   c              
   C   sB   |t @ rt| |||S | j t| |||W  5 Q R  S Q R X dS )zA send_pyobj method that's safe to use when multiple
        greenthreads are calling send, send_pyobj, recv and
        recv_pyobj on the same socket.
        N)r^   _Socket_send_pyobjrE   )r   objrc   protocolr   r   r   
send_pyobjQ  s    zSocket.send_pyobjc              
   K   sF   |t @ rt| ||f|S | j t| ||f|W  5 Q R  S Q R X dS )zA send_json method that's safe to use when multiple
        greenthreads are calling send, send_json, recv and
        recv_json on the same socket.
        N)r^   _Socket_send_jsonrE   )r   rq   rc   kwargsr   r   r   	send_json_  s    zSocket.send_jsonc                 C   s$  |t @ r.t| |||}| j  | j  |S d}ttdrt| tj}|dkrRn"|dkrl| 	 |d  }nt
||t O }| j zz t| |||W W nW  5 Q R  S  tk
r } z<|jtkr|dk	r| 	 |krd|_ | jj|d n W 5 d}~X Y nX W 5 | j  X qW 5 Q R X dS )zA recv method that's safe to use when multiple greenthreads
        are calling send, send_multipart, recv and recv_multipart on
        the same socket.
        NRCVTIMEOr   g     @@T)r8   )r^   _Socket_recvrC   r6   rD   hasattr__zmq__rT   rw   rO   
ValueErrorrF   r;   r`   ra   Z
is_timeoutr9   )r   rc   rd   re   rb   r8   sock_timeoutrf   r   r   r   recvm  s2    


 
zSocket.recvc              
   C   sB   |t @ rt| |||S | j t| |||W  5 Q R  S Q R X dS )zA recv_multipart method that's safe to use when multiple
        greenthreads are calling send, send_multipart, recv and
        recv_multipart on the same socket.
        N)r^   _Socket_recv_multipartrF   )r   rc   rd   re   r   r   r   recv_multipart  s    zSocket.recv_multipartc              
   C   s>   |t @ rt| ||S | j t| ||W  5 Q R  S Q R X dS )zA recv_string method that's safe to use when multiple
        greenthreads are calling send, send_string, recv and
        recv_string on the same socket.
        N)r^   _Socket_recv_stringrF   )r   rc   rm   r   r   r   recv_string  s    zSocket.recv_stringc              
   K   sB   |t @ rt| |f|S | j t| |f|W  5 Q R  S Q R X dS )zA recv_json method that's safe to use when multiple
        greenthreads are calling send, send_json, recv and
        recv_json on the same socket.
        N)r^   _Socket_recv_jsonrF   )r   rc   ru   r   r   r   	recv_json  s    zSocket.recv_jsonc              
   C   s:   |t @ rt| |S | j t| |W  5 Q R  S Q R X dS )zA recv_pyobj method that's safe to use when multiple
        greenthreads are calling send, send_pyobj, recv and
        recv_pyobj on the same socket.
        N)r^   _Socket_recv_pyobjrF   )r   rc   r   r   r   
recv_pyobj  s    
zSocket.recv_pyobj)N)r   TF)r   TF)r   Trj   )r   ro   )r   )r   TF)r   TF)r   rj   )r   )r   )r   r   r   r/   r   rB   _SocketrX   rT   rg   ri   rn   rs   rv   r~   r   r   r   r   __classcell__r   r   rV   r   r      s4   	
!-)2r/   
__import__r{   Zeventlet.hubsr   Zeventlet.patcherr   Zeventlet.supportr   r&   Z__patched__globalscollectionsr   rz   ZDEALERr   ZROUTERr	   	NameErrorr4   r
   r   r1   r   rB   r   r   r~   ry   rg   r_   ri   rh   r   r   rn   rk   r   r   rs   rp   r   r   rv   rt   r   r   rT   rG   r   r   r   r   <module>   s@   

2.4