
    <|hQ                     ,   d dl mZmZmZ 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	 Z e        e       d
<   [d dlmZ d dlmZ d dlmZ  G d de      Z e       Z e       Z G d de      Z G d de      Zd dlmZ  e e       d       y)    )print_functionabsolute_importdivision	SemaphoreBoundedSemaphore)sleep)	monotonic)InvalidThreadUseError)LoopExit)Timeoutc                  D    t        d      } | j                  j                  S )Nzgevent._abstract_linkable)
__import___abstract_linkableAbstractLinkable)xs    P/var/www/html/test/engine/venv/lib/python3.12/site-packages/gevent/_semaphore.py_get_linkabler      s    ./A000    r   )get_hub_if_exists)get_hub)	spawn_rawc                       e Zd ZdZd Zd Zy)_LockReleaseLinklockc                     || _         y Nr   )selfr   s     r   __init__z_LockReleaseLink.__init__'   s	    	r   c                 8    | j                   j                          y r   )r   release)r   _s     r   __call__z_LockReleaseLink.__call__*   s    		r   N)__name__
__module____qualname__	__slots__r   r#    r   r   r   r   "   s    Ir   r   c                        e Zd ZdZdZd fd	Zd Zd Zd Zd Z	d Z
d	 Zdd
ZddZeZd Zd Zd Zd Zd Zd Zd Zd Zd Zd Z xZS )r   ap  
    Semaphore(value=1) -> Semaphore

    .. seealso:: :class:`BoundedSemaphore` for a safer version that prevents
       some classes of bugs. If unsure, most users should opt for `BoundedSemaphore`.

    A semaphore manages a counter representing the number of `release`
    calls minus the number of `acquire` calls, plus an initial value.
    The `acquire` method blocks if necessary until it can return
    without making the counter negative. A semaphore does not track ownership
    by greenlets; any greenlet can call `release`, whether or not it has previously
    called `acquire`.

    If not given, ``value`` defaults to 1.

    The semaphore is a context manager and can be used in ``with`` statements.

    This Semaphore's ``__exit__`` method does not call the trace function
    on CPython, but does under PyPy.

    .. versionchanged:: 1.4.0
        Document that the order in which waiters are awakened is not specified. It was not
        specified previously, but due to CPython implementation quirks usually went in FIFO order.
    .. versionchanged:: 1.5a3
       Waiting greenlets are now awakened in the order in which they waited.
    .. versionchanged:: 1.5a3
       The low-level ``rawlink`` method (most users won't use this) now automatically
       unlinks waiters before calling them.
    .. versionchanged:: 20.12.0
       Improved support for multi-threaded usage. When multi-threaded usage is detected,
       instances will no longer create the thread's hub if it's not present.

    .. versionchanged:: 24.2.1
       Uses Python 3 native lock timeouts for cross-thread operations instead
       of spinning.
    )counter_multithreadedc                     || _         | j                   dk  rt        d      t        t        |   |       d| _        t        | _        y )Nr   z$semaphore initial value must be >= 0F)r*   
ValueErrorsuperr   r   _notify_all_UNSETr+   )r   valuehub	__class__s      r   r   zSemaphore.__init__`   sA    <<!CDDi', $r   c                 ~    d| j                   j                  t        |       | j                  | j	                         fz  S )Nz"<%s at 0x%x counter=%s _links[%s]>)r3   r$   idr*   	linkcountr   s    r   __str__zSemaphore.__str__h   s9    3NN##tHLLNN	7
 
 	
r   c                      | j                   dk  S )z
        Return a boolean indicating whether the semaphore can be
        acquired (`False` if the semaphore *can* be acquired). Most
        useful with binary semaphores (those with an initial value of 1).

        :rtype: bool
        r   r*   r7   s    r   lockedzSemaphore.lockedp   s     ||q  r   c                 d    | xj                   dz  c_         | j                          | j                   S )a  
        Release the semaphore, notifying any waiters if needed. There
        is no return value.

        .. note::

            This can be used to over-release the semaphore.
            (Release more times than it has been acquired or was initially
            created with.)

            This is usually a sign of a bug, but under some circumstances it can be
            used deliberately, for example, to model the arrival of additional
            resources.

        :rtype: None
           )r*   _check_and_notifyr7   s    r   r!   zSemaphore.releasez   s(    " 	 ||r   c                      | j                   dkD  S )z
        Return a boolean indicating whether the semaphore can be
        acquired (`True` if the semaphore can be acquired).

        :rtype: bool
        r   r:   r7   s    r   readyzSemaphore.ready   s     ||ar   c                 $    | j                          y r   )r>   r7   s    r   _start_notifyzSemaphore._start_notify   s     r   c                     |r|S yNTr(   )r   waitedwait_successs      r   _wait_return_valuezSemaphore._wait_return_value   s     r   c                 r    | j                   dkD  r| j                   S | j                  |       | j                   S )aD  
        Wait until it is possible to acquire this semaphore, or until the optional
        *timeout* elapses.

        .. note:: If this semaphore was initialized with a *value* of 0,
           this method will block forever if no timeout is given.

        :keyword float timeout: If given, specifies the maximum amount of seconds
           this method will block.
        :return: A number indicating how many times the semaphore can be acquired
            before blocking. *This could be 0,* if other waiters acquired
            the semaphore.
        :rtype: int
        r   )r*   _wait)r   timeouts     r   waitzSemaphore.wait   s0     <<!<<

7||r   c                 2   | j                   t        u r| j                         | _         n(| j                   | j                         k7  rt        | _         d}	 | j	                  d       | j                  dkD  r| xj                  dz  c_        y|sy| j                   t        ur| j                  t               | _	        | j                  '|s%| j                  dd| j                         df||      S 	 | j                  |      }|s|J y| j                  dkD  sJ | j                  |||f       | xj                  dz  c_        y# t
        $ r?}|j                  }d}| j                  s|r| j                  |||      cY d}~S Y d}~d}~ww xY w# t        $ r}|j                  }d}| j                  rd}nZt        |      dk(  r|d   j                  r | j                  | j                  t!               | j                         df||      cY d}~S Y d}~d}~ww xY w)	a"  
        acquire(blocking=True, timeout=None) -> bool

        Acquire the semaphore.

        .. note:: If this semaphore was initialized with a *value* of 0,
           this method will block forever (unless a timeout is given or blocking is
           set to false).

        :keyword bool blocking: If True (the default), this function will block
           until the semaphore is acquired.
        :keyword float timeout: If given, and *blocking* is true,
           specifies the maximum amount of seconds
           this method will block.
        :return: A `bool` indicating whether the semaphore was acquired.
           If ``blocking`` is True and ``timeout`` is None (the default), then
           (so long as this semaphore was initialized with a size greater than 0)
           this will always return True. If a timeout was given, and it expired before
           the semaphore was acquired, False will be returned. (Note that this can still
           raise a ``Timeout`` exception, if some other caller had already started a timer.)
        NFr   r=   TNoHubs   r   )r+   r0   _get_thread_ident_MULTI_capture_hubr
   argsr*   %_Semaphore__acquire_from_other_threadr2   r   _getcurrentrI   r   lenmain_hubr   )r   blockingrJ   invalid_thread_useesuccessexrR   s           r   acquirezSemaphore.acquire   s   0 &("&"8"8":D  D$:$:$<<"(D "		_e$ <<!LLALf,1AyDH88$6 33tT--/: 	jj)G  &&& ||aL$,,'7!LLs % 	_ "#A<<H778JHV]^^	_B  	77DB|| t9>d1g&6&677XX02D4D4D4F
S  		s=   E  .F  	F	.F7FF	HA1HHHc                 $    | j                          y r   )r\   r7   s    r   	__enter__zSemaphore.__enter__      r   c                 $    | j                          y r   )r!   )r   tvtbs       r   __exit__zSemaphore.__exit__  r_   r   c                 :    | j                   j                  |       y r   )_linksextend)r   
unswitcheds     r    _handle_unswitched_notificationsz*Semaphore._handle_unswitched_notifications   s    . 	:&r   c                     | j                   s| j                  |       y | j                   j                  d   j                  |       y )Nr   )	_notifierrawlinkrR   append)r   links     r   
__add_linkzSemaphore.__add_link9  s2    ~~LLNN"))$/r   c                     |sJ |d   }|d   }|d   }||| j                  |      S || j                  ||      S | j                  |||      S )Nr   r=      ) _Semaphore__acquire_without_hubs#_Semaphore__acquire_using_other_hub"_Semaphore__acquire_using_two_hubs)r   ex_argsrW   rJ   
owning_hubhub_for_this_threadcurrent_greenlets          r   __acquire_from_other_threadz%Semaphore.__acquire_from_other_thread?  s~    x QZ
%aj"1:"5"=..w77& 11*gFF ,,-@-=-46 	6r   c                    |j                   j                         }|j                  }|j                  |j                  |        	 t        j                  |      5 }	 	 | j                  dkD  rg| xj                  dz  c_        | j                  dk\  sJ | f       	 d d d        | j                  |       |j                          |j                          y| j                  |       | j                  |       | j                  d      }|r<|cd d d        | j                  |       |j                          |j                          S # t
        $ rH}||ur Y d }~d d d        | j                  |       |j                          |j                          yd }~ww xY w# 1 sw Y   nxY w	 | j                  |       |j                          |j                          y # | j                  |       |j                          |j                          w xY w)Nr=   r   TF)loopasync_send_ignoring_argstartswitchr   _start_new_or_dummyr*   _quiet_unlink_allstopclose_Semaphore__add_link_switch_to_hubr\   )	r   rw   rx   rJ   watchersendtimerresulttexs	            r   __acquire_using_two_hubsz"Semaphore.__acquire_using_two_hubsd  s    &**113((&--t4	,,W5 !!<<!+ LLA-L#'<<1#4=tg=#4#'!4 ""4(LLNMMO% - ++,?@
 "&a!#))! !4 ""4(LLNMMO1 "  !%' 1!4 ""4(LLNMMO!+! ! !4 ""4(LLNMMO ""4(LLNMMOs`   G F<EG 6E	G E	FFFG FFF!G 3H
c                     	 | j                  ||      }|j                  |       |j                          |S # |j                          w xY wr   )r\   rm   r!   )r   resultsrW   rJ   thread_lockr   s         r   __acquire_from_other_thread_cbz(Semaphore.__acquire_from_other_thread_cb  sD    	"\\(G4FNN6"! !s	   #7 A	c                     |t               usJ | j                         }|j                          g }|j                  j	                  t
        | j                  |d||       | j                  |d        |d   S )Nr=   r   )r   _allocate_lockr\   r{   run_callback_threadsafer   (_Semaphore__acquire_from_other_thread_cb_Semaphore__spin_on_native_lock)r   rv   rJ   r   r   s        r   __acquire_using_other_hubz#Semaphore.__acquire_using_other_hub  sy    !2!4444))+////	 	"";5qzr   c                 n   | j                         }|j                          d}d}|rt               |z   }t        |      }	 | j	                  |       |r
t               }| j                  ||      }| j                  |       |r| j                  d      ry|r t               }||k\  ry||z
  }||z  }|dk  ryw)Nr   TF)r   r\   r	   r   r   r   r   )	r   rJ   r   absolute_expirationbeginrn   
got_nativenowdurations	            r   __acquire_without_hubsz Semaphore.__acquire_without_hubs  s    ))+"++"7  ,OOD!"!33KIJ""4(<<?"k-- ;8#a< # r   c                     | j                          	 |r"|j                  d|      | j                          S |j                         | j                          S # | j                          w xY wrD   )_drop_lock_for_switch_outr\   _acquire_lock_for_switch_in)r   r   rJ   s      r   __spin_on_native_lockzSemaphore.__spin_on_native_lock  s]    &&(
	/
 "**49 ,,. &&(,,.D,,.s   A A A()r=   Nr   )TN)r$   r%   r&   __doc__r'   r   r8   r;   r!   r@   rB   rG   rK   r\   _py3k_acquirer^   rd   ri   r   rS   rt   r   rs   rr   r   __classcell__r3   s   @r   r   r   0   sz    #JI%
!* !*^@ M'20#6J(T(!:/r   c                   6     e Zd ZdZdZeZd Zd Z fdZ	 xZ
S )r   a  
    BoundedSemaphore(value=1) -> BoundedSemaphore

    A bounded semaphore checks to make sure its current value doesn't
    exceed its initial value. If it does, :class:`ValueError` is
    raised. In most situations semaphores are used to guard resources
    with limited capacity. If the semaphore is released too many times
    it's a sign of a bug.

    If not given, *value* defaults to 1.
    )_initial_valuec                 X    t        j                  | g|i | | j                  | _        y r   )r   r   r*   r   )r   rR   kwargss      r   r   zBoundedSemaphore.__init__  s&    41$1&1"llr   c                     | j                   | j                  k\  r| j                  d      t        j	                  |       }|| j                  k(  rd| _        |S )z
        Like :meth:`Semaphore.release`, but raises :class:`ValueError`
        if the semaphore is being over-released.
        z!Semaphore released too many timesN)r*   r   _OVER_RELEASE_ERRORr   r!   r2   )r   r*   s     r   r!   zBoundedSemaphore.release  sT    
 <<4...**+NOO##D) d)))DHr   c                 L    t         t        |           | j                  | _        y r   )r.   r   _at_fork_reinitr   r*   )r   r3   s    r   r   z BoundedSemaphore._at_fork_reinit  s    57**r   )r$   r%   r&   r   r'   r-   r   r   r!   r   r   r   s   @r   r   r     s+    
I
 %++ +r   )import_c_accelzgevent.__semaphoreN) 
__future__r   r   r   __all__timer   _native_sleepgevent._compatr	   gevent.exceptionsr
   r   gevent.timeoutr   r   localsgevent._hub_localr   r   
gevent.hubr   objectr   r0   rP   r   r   r   gevent._utilr   globalsr(   r   r   <module>r      s    A @ 
 ( $ 3 & "1  -	  / %  	v 	 
	c/  c/L)+y )+p ( wy. /r   