U

����� g�����������������������@���s����d�Z�ddlZddlZddlZddlZddlmZ�ddlZ	ddddgZ
e��Zda
dd��ZG�d	d��de�ZG�d
d��de�ZG�dd��de�ZdS�)ag��!Handles file locking using Python "with" blocks.

This module implements a Python with construct that can hold a lock
and release it at the end of the "with" block.  It also implements a
safety feature to allow the program to disable locking, ensuring a
fatal exception (LockingDisabled) if anything tries to lock a file.
That functionality is connected to the produtil.sigsafety module,
which will disable locking if a fatal signal is received.

@code
import produtil.locking
with produtil.locking.LockFile("some.lockfile"):
    ... do things while the file is locked...
...  the file is now unlocked ...
@endcode�����N�LockingDisabled�disable_locking�LockFile�LockHeldTc������������������C���sF���da�tD�]8}�z|�����W�q�ttfk
r>�}�zW�5�d}~X�Y�qX�qdS�)ac��!Entirely disables all locking in this module.  

    If this is called, any locking attempts will raise
    LockingDisabled.  That exception derives directly from
    BaseException, which well-written Python code will never catch,
    hence ensuring a rapid, abnormal exit of the program.  This
    routine should never be called directly: it is only used as part
    of the implementation of the produtil.sigsafety, to prevent file
    locking after catching a terminal signal, hence allowing the
    program to exit as quickly as possible, and present a stack trace
    to any locations that attempt locking.FN)�
locks_okay�locks�release_impl�	Exceptionr���)�lock�l��r����=/lfs/h1/ops/prod/packages/hmon.v3.2.7/ush/produtil/locking.pyr���%���s����
�c�������������������@���s���e�Zd�ZdZdS�)r���zy!This exception is raised when a LockFile cannot lock a file
    because another process or thread has locked it already.N��__name__�
__module__�__qualname__�__doc__r���r���r���r
���r���8���s���c�������������������@���s���e�Zd�ZdZdS�)r���z�!This exception is raised when a thread attempts to acquire a
    lock while Python is exiting according to produtil.sigsafety.
    
    @warning This is a subclass of BaseException, not Exception, to
    attempt to cleanly kill the thread.Nr���r���r���r���r
���r���<���s���c�������������������@���sZ���e�Zd�ZdZdd��Zdd��Zddd�Zd
d��Zdd��Zdd��Z	dd��Z
dd��Zdd��ZdS�)r���z�!Automates locking of a lockfile

    @code
      with LockFile("/path/to/lock.file"):
          ... do things while file is locked ...
      ...file is no longer locked.
    @endcodec�����������������C���s���t�t|���S�)z!Return a hash of this object.)�hash�id��selfr���r���r
����__hash__K���s����zLockFile.__hash__c�����������������C���s���|�|kS�)z$!Is this lock the same as that lock?r���)r����otherr���r���r
����__eq__N���s����zLockFile.__eq__N�
�������r���Fc�����������������C���sV���t�std��||�_|dk	st�t|�dks.t�||�_||�_||�_||�_||�_	d|�_
dS�)a5��!Creates an object that will lock the specified file.  
        @param filename the file to lock
        @param until Unused.
        @param logger Optional: a logging.Logger to log messages
        @param max_tries Optional: maximum tries before giving up on locking
        @param sleep_time Optional: approximate sleep time between
          locking attempts.
        @param first_warn Optional: first locking failure at which to
          write warnings to the logger
        @param giveup_quiet Optional: if True, do not log the final
          failure to lockzDAttempted to create a LockFile object while the process was exiting.Nr���)r���r����_logger�AssertionError�len�	_filename�
_max_tries�_sleep_time�_first_warn�
_giveup_quiet�_fd)r����filenameZuntil�logger�	max_triesZ
sleep_time�
first_warn�giveup_quietr���r���r
����__init__Q���s����zLockFile.__init__c��������������
���C���s����t�std��tj�|�j�}|r*tj�|��|�j	dkrBt
|�jd�|�_	zt�|�j	�
��tjtjB���W�nR�tk
r��}�z4|jtjks�|jtjkr�td|�jt|�f�����W�5�d}~X�Y�nX�dS�)z�!Internal implementation function; do not call directly.
        Does the actual work of acquiring the lock, without retries,
        logging or sleeping.  Will raise LockHeld if it cannot acquire
        the lock.z:Attempted to acquire a lock while the process was exiting.N�wbz3%s: already locked by another process or thread: %s)r���r����os�path�dirnamer����produtil�fileop�makedirsr$����open�fcntl�lockf�fileno�LOCK_EX�LOCK_NB�EnvironmentError�errno�EAGAIN�EWOULDBLOCKr����str)r���Zthedir�er���r���r
����acquire_implh���s����
�zLockFile.acquire_implc�����������������C���s2���|�j�dk	r.t�|�j����tj��|�j�����d|�_�dS�)z�!Internal implementation function; do not call directly.
        Does the actual work of releasing the lock, without retries,
        logging or sleeping.N)r$���r3���r4���r5����LOCK_UN�closer���r���r���r
���r���|���s����

zLockFile.release_implc��������������	���C���s4���t��|���tj|�j|�j|�j|�jd�|�j|�j	|�j
d�S�)zY!Acquire the lock.  Will try for a while, and will raise
        LockHeld when giving up.z
: cannot lock�Zfailr&���r(���r)���)r����add�retry�retry_ior ���r!���r>���r���r���r"���r#���r���r���r���r
����acquire����s����
���zLockFile.acquirec��������������	���C���sJ���z,t�j|�j|�j|�j|�jd�|�j|�j|�jd�W�S������Y�nX�t	�
|���dS�)zH!Release the lock.  May raise exceptions on unexpected
        failures.z: cannot unlockrA���N)rC���rD���r ���r!���r���r���r���r"���r#���r����remover���r���r���r
����release����s�������zLockFile.releasec�����������������C���s���|������|�S�)z*!Calls self.acquire() to acquire the lock.)rE���r���r���r���r
����	__enter__����s����zLockFile.__enter__c�����������������C���s���|������dS�)zh!Calls self.release() to release the lock.
        @param etype,evalue,etraceback Exception information.N)rG���)r����etypeZevalueZ
etracebackr���r���r
����__exit__����s����zLockFile.__exit__)NNr���r���r���F)
r���r���r���r���r���r���r*���r>���r���rE���rG���rH���rJ���r���r���r���r
���r���C���s���
)r���r3����timer9���Zos.pathr,���Zprodutil.retryrC����produtil.fileopr/����__all__�setr���r���r���r	���r����
BaseExceptionr����objectr���r���r���r���r
����<module>���s���