Current File : //usr/lib64/python3.6/site-packages/borg/__pycache__/locking.cpython-36.pyc
3

y��b�9�@s�ddlZddlZddlZddlZddlmZddlmZmZddl	m
Z
d\ZZd\Z
Ze
e�Z	Gd
d�d�ZGdd
�d
e�ZGdd�de�ZGdd�de�ZGdd�de�ZGdd�de�ZGdd�de�ZGdd�d�ZGdd�d�ZGdd�d�ZdS) �N�)�platform)�Error�ErrorWithTraceback)�
create_logger�add�remove�shared�	exclusivec@sBeZdZdZddd�Zdd�Zdd�Zd	d
�Zdd�Zd
d�Z	dS)�TimeoutTimerz�
    A timer for timeout checks (can also deal with "never timeout").
    It can also compute and optionally execute a reasonable sleep time (e.g. to avoid
    polling too often or to support thread/process rescheduling).
    NcCsX|dk	r|dkrtd��||_|dkrB|dkr4d}ntd|d�}||_d|_d|_dS)ag
        Initialize a timer.

        :param timeout: time out interval [s] or None (never timeout, wait forever) [default]
        :param sleep: sleep interval [s] (>= 0: do sleep call, <0: don't call sleep)
                      or None (autocompute: use 10% of timeout [but not more than 60s],
                      or 1s for "never timeout" mode)
        Nrztimeout must be >= 0g�?gN@g$@)�
ValueError�timeout_interval�min�sleep_interval�
start_time�end_time)�self�timeout�sleep�r�/usr/lib64/python3.6/locking.py�__init__s	zTimeoutTimer.__init__cCsd|jj|j|j|j|jfS)Nz)<%s: start=%r end=%r timeout=%r sleep=%r>)�	__class__�__name__rrr
r)rrrr�__repr__+szTimeoutTimer.__repr__cCs&tj�|_|jdk	r"|j|j|_|S)N)�timerr
r)rrrr�start0s

zTimeoutTimer.startcCs|jdkrtj|j�dS)Nr)rrr)rrrrr6s
zTimeoutTimer.sleepcCs|jdk	otj�|jkS)N)rr)rrrr�	timed_out:szTimeoutTimer.timed_outcCs|j�rdS|j�dSdS)NTF)rr)rrrr�timed_out_or_sleep=szTimeoutTimer.timed_out_or_sleep)NN)
r�
__module__�__qualname__�__doc__rrrrrrrrrrrs
rc@seZdZdZdS)�	LockErrorzFailed to acquire the lock {}.N)rrr r!rrrrr"Esr"c@seZdZdZdS)�
LockErrorTzFailed to acquire the lock {}.N)rrr r!rrrrr#Isr#c@seZdZdZdS)�LockTimeoutz/Failed to create/acquire the lock {} (timeout).N)rrr r!rrrrr$Msr$c@seZdZdZdS)�
LockFailedz*Failed to create/acquire the lock {} ({}).N)rrr r!rrrrr%Qsr%c@seZdZdZdS)�	NotLockedz/Failed to release the lock {} (was not locked).N)rrr r!rrrrr&Usr&c@seZdZdZdS)�	NotMyLockz=Failed to release the lock {} (was/is locked, but not by me).N)rrr r!rrrrr'Ysr'c@sleZdZdZddd�Zdd�Zdd	�Zd
d�Zddd
�Zdd�Z	dd�Z
dd�Zdd�Zdd�Z
dd�ZdS)�
ExclusiveLocka/An exclusive Lock based on mkdir fs operation being atomic.

    If possible, try to use the contextmanager here like::

        with ExclusiveLock(...) as lock:
            ...

    This makes sure the lock is released again if the block is left, no
    matter how (e.g. if an exception occurred).
    NFcCsP||_||_tjj|�|_|p$tj�|_tjj|jd|j�|_	||_
d|_dS)Nz%s.%d-%xF)rr�os�path�abspathr�get_process_id�id�join�unique_name�kill_stale_locks�stale_warning_printed)rr*rrr-r0rrrrhszExclusiveLock.__init__cCs|j�S)N)�acquire)rrrr�	__enter__qszExclusiveLock.__enter__cGs|j�dS)N)�release)r�excrrr�__exit__tszExclusiveLock.__exit__cCsd|jj|jfS)Nz<%s: %r>)rrr/)rrrrrwszExclusiveLock.__repr__cCs�|dkr|j}|dkr|j}t||�j�}x�ytj|j�Wnltk
rv|j�rX|S|j	�|j
�rrt|j��Yq,tk
r�}zt
|jt|��d�WYdd}~Xq,Xt|jd��WdQRX|Sq,WdS)N�wb)rrrrr)�mkdirr*�FileExistsError�by_me�kill_stale_lockrr$�OSErrorr%�str�openr/)rrr�timer�errrrrr2zs&$
zExclusiveLock.acquirecCs@|j�st|j��|j�s$t|j��tj|j�tj|j�dS)N)	�	is_lockedr&r*r:r'r)�unlinkr/�rmdir)rrrrr4�s

zExclusiveLock.releasecCstjj|j�S)N)r)r*�exists)rrrrrA�szExclusiveLock.is_lockedcCstjj|j�S)N)r)r*rDr/)rrrrr:�szExclusiveLock.by_mec
"Cs�ytj|j�}Wntk
r$dSX�x|D�]�}y4|jdd�\}}|jdd�\}}t|�}t|�}Wn$tk
r�tjd||j�dSXt	j
|||�r�dS|js�|js�tj
d|�d|_dSy&tjtjj|j|��tj
d|�Wq.tk
�r*}	z$|j�stjd	|t|	��d|_dSd}	~	Xq.Xq.Wytj|j�WnDtk
�r�}	z&|	jtjk�rfdStjd
t|	��dSd}	~	XnXdS)NF�-r�.z9Found malformed lock %s in %s. Please check/fix manually.zOFound stale lock %s, but not deleting because BORG_HOSTNAME_IS_UNIQUE is False.TzKilled stale lock %s.z0Found stale lock %s, but cannot delete due to %szFailed to remove lock dir: %s)r)�listdirr*�FileNotFoundError�rsplit�intr�logger�errorr�
process_aliver0r1�warningrBr.r<r=rC�errnoZ	ENOTEMPTY)
r�names�nameZhost_pidZ
thread_str�hostZpid_str�pid�threadr@rrrr;�sHzExclusiveLock.kill_stale_lockcCsD|j�r@x*tj|j�D]}tjtjj|j|��qWtj|j�dS)N)rAr)rGr*rBr.rC)rrQrrr�
break_lock�szExclusiveLock.break_lockc
Csf|j|kst�tjj|jd|�}|j�rT|j�rTt|d��WdQRXtj|j	�|||_|_	dS)z0migrate the lock ownership from old_id to new_idz%s.%d-%xr7N)
r-�AssertionErrorr)r*r.rAr:r>rBr/)r�old_id�new_idZnew_unique_namerrr�migrate_lock�s
zExclusiveLock.migrate_lock)NNNF)NN)rrr r!rr3r6rr2r4rAr:r;rUrYrrrrr(]s

	
2r(c@sReZdZdZddd�Zdd�Zdd	�Zd
d�Zdd
�Zdd�Z	dd�Z
dd�ZdS)�
LockRosterz�
    A Lock Roster to track shared/exclusive lockers.

    Note: you usually should call the methods with an exclusive lock held,
    to avoid conflicting access by multiple threads/processes/machines.
    NFcCs||_|ptj�|_||_dS)N)r*rr,r-r0)rr*r-r0rrrr�szLockRoster.__init__c	Cs�y�t|j��}tj|�}WdQRX|jr�x�ttfD]�}y||}Wntk
rXw2YnXt�}xD|D]<\}}}t	j
|||�r�|j|||f�qftj
d||||�qfWt|�||<q2WWnttfk
r�i}YnX|S)Nz:Removed stale %s roster lock for host %s pid %d thread %d.)r>r*�json�loadr0�SHARED�	EXCLUSIVE�KeyError�setrrMrrKrN�listrHr)	r�f�data�keyZentries�elementsrRrSrTrrrr\�s&
zLockRoster.loadc
Cs(t|jd��}tj||�WdQRXdS)N�w)r>r*r[�dump)rrcrbrrr�saveszLockRoster.savecCs*ytj|j�Wntk
r$YnXdS)N)r)rBr*rH)rrrrr
szLockRoster.removecCs"|j�}tdd�|j|g�D��S)Ncss|]}t|�VqdS)N)�tuple)�.0�errr�	<genexpr>sz!LockRoster.get.<locals>.<genexpr>)r\r`�get)rrd�rosterrrrrmszLockRoster.getcst�fdd�|D��S)Nc3s|]}�j|�VqdS)N)rm)rjrd)rrrrlsz#LockRoster.empty.<locals>.<genexpr>)�all)r�keysr)rr�emptyszLockRoster.emptycCs�|j�}ytdd�||D��}Wntk
r<t�}YnX|tkrT|j|j�n"|tkrj|j|j�ntd|��t	dd�|D��||<|j
|�dS)Ncss|]}t|�VqdS)N)ri)rjrkrrrrlsz$LockRoster.modify.<locals>.<genexpr>zUnknown LockRoster op %rcss|]}t|�VqdS)N)ra)rjrkrrrrl#s)r\r`r_�ADDrr-�REMOVErrrarh)rrd�oprnrerrr�modifyszLockRoster.modifycCsl|j|kst�|jd}|_zBy|j|t�Wntk
rH||_YnX||_|j|t�Wd||_XdS)z0migrate the lock ownership from old_id to new_idFN)r-rVr0rursr_rr)rrdrWrXZkillingrrrrY&szLockRoster.migrate_lock)NF)rrr r!rr\rhrrmrqrurYrrrrrZ�s
rZc@steZdZdZddd�Zdd�Zdd	�Zd
d�Zddd
�Zdd�Z	dd�Z
dd�Zdd�Zdd�Z
dd�Zdd�ZdS)�Locka�
    A Lock for a resource that can be accessed in a shared or exclusive way.
    Typically, write access to a resource needs an exclusive lock (1 writer,
    no one is allowed reading) and read access to a resource needs a shared
    lock (multiple readers are allowed).

    If possible, try to use the contextmanager here like::

        with Lock(...) as lock:
            ...

    This makes sure the lock is released again if the block is left, no
    matter how (e.g. if an exception occurred).
    FNcCsT||_||_||_||_|p"tj�|_t|d||d�|_t	|d|||d�|_
dS)Nz.roster)r-r0z
.exclusive)r-rr0)r*�is_exclusiverrrr,r-rZ�_rosterr(�_lock)rr*r
rrr-r0rrrrIsz
Lock.__init__cCs|j�S)N)r2)rrrrr3VszLock.__enter__cGs|j�dS)N)r4)rr5rrrr6Ysz
Lock.__exit__cCsd|jj|jfS)Nz<%s: %r>)rrr-)rrrrr\sz
Lock.__repr__c
Cs||dkr|j}|p|jpd}|r<|j||�|jjtt�n6|j�*|dk	rZ|jj|t�|jjt	t�WdQRX||_|S)Ng�������?)
rwr�_wait_for_readers_finishingrxrur^rrryrsr])rr
rrrrrr2_szLock.acquirec	Cs�t|j|�j�}x�|jj�yH|dk	r4|jj|t�t|jj	t
��dkrLdS|dk	rb|jj|t�Wn|jj��YnX|jj�|j
�rt|j��qWdS)Nr)rrrryr2rxrurs�lenrmr]rrr4rr$r*)rrrr?rrrrzns 


z Lock._wait_for_readers_finishingc
Cst|jr8|jjtt�|jjtt�r,|jj�|jj	�n8|j�,|jjtt�|jjtt�rf|jj�WdQRXdS)N)
rwrxrur^rsrqr]rryr4)rrrrr4�s
zLock.releasecCs|js|jdtd�dS)NT)r
r)rwr2r])rrrr�upgrade�szLock.upgradecCs|jr|jdtd�dS)NF)r
r)rwr2r^)rrrr�	downgrade�szLock.downgradecCs|jo|jj�o|jj�S)N)rwryrAr:)rrrr�got_exclusive_lock�szLock.got_exclusive_lockcCs|jj�|jj�dS)N)rxrryrU)rrrrrU�s
zLock.break_lockcCsn|j|kst�||_|jr:|jj||�|jjt||�n0|j�$|jj||�|jjt||�WdQRXdS)N)r-rVrwryrYrxr^r])rrWrXrrrrY�szLock.migrate_lock)FNNNF)NNN)rrr r!rr3r6rr2rzr4r|r}r~rUrYrrrrrv:s


rv)rr)r	r
)rOr[r)r�rZhelpersrrrKrrrrsr]r^rrr"r#r$r%r&r'r(rZrvrrrr�<module>s(5Y