o
    tPfQ                     @   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   R/var/www/html/humari/django-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rd}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sJ dS | jdksJ | 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|  zt|}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 sw   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