o
    ,wÖi—Q  ã                   @   sê   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	d
„ Zeƒ eƒ d< [d dlmZ d dlmZ d dlmZ G dd„ deƒZeƒ Zeƒ ZG dd„ deƒZG dd„ deƒZd dlmZ eeƒ dƒ dS )é    )Úprint_functionÚabsolute_importÚdivisionÚ	SemaphoreÚBoundedSemaphore)Úsleep)Ú	monotonic)ÚInvalidThreadUseError)ÚLoopExit)ÚTimeoutc                  C   s   t dƒ} | jjS )Nzgevent._abstract_linkable)Ú
__import__Ú_abstract_linkableÚAbstractLinkable)Úx© r   úN/home/ubuntu/sommelier/.venv/lib/python3.10/site-packages/gevent/_semaphore.pyÚ_get_linkable   s   r   r   )Úget_hub_if_exists)Úget_hub)Ú	spawn_rawc                   @   s    e Zd ZdZdd„ Zdd„ ZdS )Ú_LockReleaseLink©Úlockc                 C   s
   || _ d S ©Nr   )Úselfr   r   r   r   Ú__init__'   s   
z_LockReleaseLink.__init__c                 C   s   | j  ¡  d S r   )r   Úrelease)r   Ú_r   r   r   Ú__call__*   s   z_LockReleaseLink.__call__N)Ú__name__Ú
__module__Ú__qualname__Ú	__slots__r   r   r   r   r   r   r   "   s    r   c                       s¾   e Zd ZdZdZd,‡ fdd„	Zdd„ Zd	d
„ Zdd„ Zdd„ Z	dd„ Z
dd„ Zd-dd„Zd.dd„ZeZdd„ Zdd„ Zdd„ Zdd„ Zd d!„ Zd"d#„ Zd$d%„ Zd&d'„ Zd(d)„ Zd*d+„ Z‡  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Ú_multithreadedé   Nc                    s8   || _ | j dk rtdƒ‚tt| ƒ |¡ d| _t| _d S )Nr   z$semaphore initial value must be >= 0F)r#   Ú
ValueErrorÚsuperr   r   Ú_notify_allÚ_UNSETr$   )r   ÚvalueÚhub©Ú	__class__r   r   r   `   s   

zSemaphore.__init__c                 C   s   d| j jt| ƒ| j|  ¡ f S )Nz"<%s at 0x%x counter=%s _links[%s]>)r-   r   Úidr#   Ú	linkcount©r   r   r   r   Ú__str__h   s   üzSemaphore.__str__c                 C   s
   | 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#   r0   r   r   r   Úlockedp   s   
zSemaphore.lockedc                 C   s   |  j d7  _ |  ¡  | 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%   )r#   Ú_check_and_notifyr0   r   r   r   r   z   s   zSemaphore.releasec                 C   s
   | j dkS )zœ
        Return a boolean indicating whether the semaphore can be
        acquired (`True` if the semaphore can be acquired).

        :rtype: bool
        r   r2   r0   r   r   r   Úready   s   
zSemaphore.readyc                 C   ó   |   ¡  d S r   )r4   r0   r   r   r   Ú_start_notify˜   ó   zSemaphore._start_notifyc                 C   s   |r|S dS ©NTr   )r   ÚwaitedÚwait_successr   r   r   Ú_wait_return_value›   s   zSemaphore._wait_return_valuec                 C   s    | j dkr| j S |  |¡ | 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   Útimeoutr   r   r   Úwait£   s   

zSemaphore.waitTc              
   C   sÆ  | j tu r|  ¡ | _ n
| j |  ¡ krt| _ d}z|  d¡ W n) tyG } z|j}d}| js=|r=|  |||¡W  Y d}~S W Y d}~nd}~ww | jdkrV|  jd8  _dS |sZdS | j turh| j	du rht
ƒ | _	| j	du r||s||  dd|  ¡ df||¡S z|  |¡}W n> tyÁ } z2|j}d}| jr–d}n!t|ƒdkr¢|d jr¢‚ |  | j	tƒ |  ¡ df||¡W  Y d}~S W Y d}~nd}~ww |sÌ|dusÊJ ‚dS | jdksÚJ | j|||fƒ‚|  jd8  _dS )	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$   r)   Ú_get_thread_identÚ_MULTIÚ_capture_hubr	   Úargsr#   Ú%_Semaphore__acquire_from_other_threadr+   r   Ú_getcurrentr=   r
   ÚlenÚmain_hubr   )r   Úblockingr>   Úinvalid_thread_useÚeÚsuccessÚexrE   r   r   r   Úacquire¸   sd   

€ù
	ýýú€üzSemaphore.acquirec                 C   r6   r   )rO   r0   r   r   r   Ú	__enter__  r8   zSemaphore.__enter__c                 C   r6   r   )r   )r   ÚtÚvÚtbr   r   r   Ú__exit__  r8   zSemaphore.__exit__c                 C   s   | j  |¡ d S r   )Ú_linksÚextend)r   Ú
unswitchedr   r   r   Ú _handle_unswitched_notifications   s   z*Semaphore._handle_unswitched_notificationsc                 C   s*   | j s
|  |¡ d S | j jd  |¡ d S )Nr   )Ú	_notifierÚrawlinkrE   Úappend)r   Úlinkr   r   r   Ú
__add_link9  s   zSemaphore.__add_linkc                 C   s\   |sJ ‚|d }|d }|d }|d u r|d u r|   |¡S |d u r'|  ||¡S |  |||¡S )Nr   r%   é   )Ú _Semaphore__acquire_without_hubsÚ#_Semaphore__acquire_using_other_hubÚ"_Semaphore__acquire_using_two_hubs)r   Úex_argsrJ   r>   Ú
owning_hubÚhub_for_this_threadÚcurrent_greenletr   r   r   Ú__acquire_from_other_thread?  s   
þz%Semaphore.__acquire_from_other_threadc           	      C   s‚  |j  ¡ }|j}| |j| ¡ z£t |¡†}zX	 | jdkrE|  jd8  _| jdks.J | fƒ‚W W d   ƒ W |  |¡ | 	¡  | 
¡  dS |  |¡ |  |¡ |  d¡}|rn|W W  d   ƒ W |  |¡ | 	¡  | 
¡  S q tyš } z ||ur{‚ W Y d }~W d   ƒ W |  |¡ | 	¡  | 
¡  dS d }~ww 1 sžw   Y  W |  |¡ | 	¡  | 
¡  d S |  |¡ | 	¡  | 
¡  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_hubrO   )	r   rd   re   r>   ÚwatcherÚsendÚtimerÚresultÚtexr   r   r   Ú__acquire_using_two_hubsd  sT   

ø

î

ì

è
è
€ùë

þ
z"Semaphore.__acquire_using_two_hubsc                 C   s0   z|   ||¡}| |¡ W | ¡  |S | ¡  w r   )rO   r[   r   )r   ÚresultsrJ   r>   Úthread_lockru   r   r   r   Ú__acquire_from_other_thread_cbŽ  s   
ÿz(Semaphore.__acquire_from_other_thread_cbc                 C   sN   |t ƒ usJ ‚|  ¡ }| ¡  g }|j t| j|d||¡ |  |d ¡ |d S )Nr%   r   )r   Ú_allocate_lockrO   rg   Úrun_callback_threadsafer   Ú(_Semaphore__acquire_from_other_thread_cbÚ_Semaphore__spin_on_native_lock)r   rc   r>   ry   rx   r   r   r   Ú__acquire_using_other_hub–  s   úz#Semaphore.__acquire_using_other_hubc           	      C   s    |   ¡ }| ¡  d}d}|rtƒ | }t|ƒ}	 |  |¡ |r"tƒ }|  ||¡}|  |¡ |r6|  d¡r6dS |rOtƒ }||krAdS || }||8 }|dkrOdS q)Nr   r%   TF)r{   rO   r   r   rp   r~   rm   )	r   r>   ry   Úabsolute_expirationÚbeginr\   Ú
got_nativeÚnowÚdurationr   r   r   Ú__acquire_without_hubsª  s2   



ïz Semaphore.__acquire_without_hubsc                 C   s@   |   ¡  z|r| d|¡W |  ¡  S | ¡ W |  ¡  S |  ¡  w r9   )Ú_drop_lock_for_switch_outrO   Ú_acquire_lock_for_switch_in)r   ry   r>   r   r   r   Ú__spin_on_native_lockÇ  s   
þzSemaphore.__spin_on_native_lock)r%   Nr   )TN)r   r    r!   Ú__doc__r"   r   r1   r3   r   r5   r7   r<   r?   rO   Ú_py3k_acquirerP   rT   rX   rp   rF   ra   r}   r`   r_   r~   Ú__classcell__r   r   r,   r   r   0   s.    %

	

`%*c                       s8   e Zd ZdZdZeZdd„ Zdd„ Z‡ fdd„Z	‡  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                 O   s$   t j| g|¢R i |¤Ž | j| _d S r   )r   r   r#   rŒ   )r   rE   Úkwargsr   r   r   r   ê  s   zBoundedSemaphore.__init__c                 C   s4   | j | jkr|  d¡‚t | ¡}|| 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   r+   )r   r#   r   r   r   r   î  s   


zBoundedSemaphore.releasec                    s   t t| ƒ ¡  | j| _d S r   )r'   r   Ú_at_fork_reinitrŒ   r#   r0   r,   r   r   r   ý  s   z BoundedSemaphore._at_fork_reinit)r   r    r!   r‰   r"   r&   rŽ   r   r   r   r‹   r   r   r,   r   r   Ö  s    )Ú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   r)   rC   r   r   r   Úgevent._utilr   Úglobalsr   r   r   r   Ú<module>   s2   	þ   )8