U
    ‰d6  ã                   @   s4   d Z ddlmZ dZG dd„ dƒZG dd„ dƒZdS )	z&Semaphores and concurrency primitives.é    )Údeque)Ú	DummyLockÚLaxBoundedSemaphorec                   @   sL   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	d
„Zddd„Zdd„ Z	dd„ Z
dS )r   aï  Asynchronous Bounded Semaphore.

    Lax means that the value will stay within the specified
    range even if released more times than it was acquired.

    Example:
        >>> x = LaxBoundedSemaphore(2)

        >>> x.acquire(print, 'HELLO 1')
        HELLO 1

        >>> x.acquire(print, 'HELLO 2')
        HELLO 2

        >>> x.acquire(print, 'HELLO 3')
        >>> x._waiters   # private, do not access directly
        [print, ('HELLO 3',)]

        >>> x.release()
        HELLO 3
    c                 C   s,   | | _ | _tƒ | _| jj| _| jj| _d S ©N)Úinitial_valueÚvaluer   Ú_waitingÚappendÚ_add_waiterÚpopleftÚ_pop_waiter)Úselfr   © r   ú@/tmp/pip-unpacked-wheel-hqfrjlvz/kombu/asynchronous/semaphore.pyÚ__init__   s    
zLaxBoundedSemaphore.__init__c                 O   sD   | j }|dkr"|  |||f¡ dS t|d dƒ| _ |||Ž dS dS )aL  Acquire semaphore.

        This will immediately apply ``callback`` if
        the resource is available, otherwise the callback is suspended
        until the semaphore is released.

        Arguments:
            callback (Callable): The callback to apply.
            *partial_args (Any): partial arguments to callback.
        r   Fé   TN)r   r
   Úmax)r   ÚcallbackÚpartial_argsZpartial_kwargsr   r   r   r   Úacquire%   s    
zLaxBoundedSemaphore.acquirec                 C   sJ   z|   ¡ \}}}W n( tk
r:   t| jd | jƒ| _Y nX |||Ž dS )z«Release semaphore.

        Note:
            If there are any waiters this will apply the first waiter
            that is waiting for the resource (FIFO order).
        r   N)r   Ú
IndexErrorÚminr   r   )r   ÚwaiterÚargsÚkwargsr   r   r   Úrelease9   s
    zLaxBoundedSemaphore.releaser   c                    s6   ˆ  j |7  _ ˆ  j|7  _‡ fdd„t|ƒD ƒ dS )z6Change the size of the semaphore to accept more users.c                    s   g | ]}ˆ   ¡ ‘qS r   )r   )Ú.0Ú_©r   r   r   Ú
<listcomp>K   s     z,LaxBoundedSemaphore.grow.<locals>.<listcomp>N)r   r   Úrange©r   Únr   r   r   ÚgrowG   s    zLaxBoundedSemaphore.growc                 C   s(   t | j| dƒ| _t | j| dƒ| _dS )z6Change the size of the semaphore to accept less users.r   N)r   r   r   r!   r   r   r   ÚshrinkM   s    zLaxBoundedSemaphore.shrinkc                 C   s   | j  ¡  | j| _dS )z@Reset the semaphore, which also wipes out any waiting callbacks.N)r   Úclearr   r   r   r   r   r   r%   R   s    
zLaxBoundedSemaphore.clearc                 C   s    d  | jjt| ƒ| jt| jƒ¡S )Nz!<{} at {:#x} value:{} waiting:{}>)ÚformatÚ	__class__Ú__name__Úidr   Úlenr   r   r   r   r   Ú__repr__W   s       ÿzLaxBoundedSemaphore.__repr__N)r   )r   )r(   Ú
__module__Ú__qualname__Ú__doc__r   r   r   r#   r$   r%   r+   r   r   r   r   r      s   

r   c                   @   s    e Zd ZdZdd„ Zdd„ ZdS )r   zPretending to be a lock.c                 C   s   | S r   r   r   r   r   r   Ú	__enter__`   s    zDummyLock.__enter__c                 G   s   d S r   r   )r   Úexc_infor   r   r   Ú__exit__c   s    zDummyLock.__exit__N)r(   r,   r-   r.   r/   r1   r   r   r   r   r   ]   s   r   N)r.   Úcollectionsr   Ú__all__r   r   r   r   r   r   Ú<module>   s   U