
­­­­­­­­­­­­­­­­­­
<!DOCTYPE html>
<html>
3
iD;                 @   s   d dl Z d dlZd dlZd dlZddlmZ ddlmZmZ ddl	m
Z
 d\ZZZd \ZZe
eZ	G dd dZG dd deZG dd deZG dd deZG dd deZG dd deZG dd deZG dd dZG dd dZG dd dZdS )!    N   )platform)ErrorErrorWithTraceback)create_loggeraddremoveremove2shared	exclusivec               @   sB   e Zd ZdZdddZdd Zdd Zd	d
 Zdd Zdd Z	dS )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).
    Nc             C   sX   |dk	r|dk rt d|| _|dkrB|dkr4d}ntd|d }|| _d| _d| _dS )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)
        Nr   ztimeout must be >= 0g      ?g      N@g      $@)
ValueErrortimeout_intervalminsleep_interval
start_timeend_time)selftimeoutsleep r   /usr/lib64/python3.6/locking.py__init__   s    	zTimeoutTimer.__init__c             C   s   d| j j| j| j| j| jf S )Nz)<%s: start=%r end=%r timeout=%r sleep=%r>)	__class____name__r   r   r   r   )r   r   r   r   __repr__+   s    zTimeoutTimer.__repr__c             C   s&   t j  | _| jd k	r"| j| j | _| S )N)timer   r   r   )r   r   r   r   start0   s    

zTimeoutTimer.startc             C   s   | j dkrtj| j  d S )Nr   )r   r   r   )r   r   r   r   r   6   s    
zTimeoutTimer.sleepc             C   s   | j d k	otj | j kS )N)r   r   )r   r   r   r   	timed_out:   s    zTimeoutTimer.timed_outc             C   s   | j  rdS | j  dS d S )NTF)r   r   )r   r   r   r   timed_out_or_sleep=   s    zTimeoutTimer.timed_out_or_sleep)NN)
r   
__module____qualname____doc__r   r   r   r   r   r   r   r   r   r   r      s   
r   c               @   s   e Zd ZdZdS )	LockErrorzFailed to acquire the lock {}.N)r   r    r!   r"   r   r   r   r   r#   E   s   r#   c               @   s   e Zd ZdZdS )
LockErrorTzFailed to acquire the lock {}.N)r   r    r!   r"   r   r   r   r   r$   I   s   r$   c               @   s   e Zd ZdZdS )LockTimeoutz/Failed to create/acquire the lock {} (timeout).N)r   r    r!   r"   r   r   r   r   r%   M   s   r%   c               @   s   e Zd ZdZdS )
LockFailedz*Failed to create/acquire the lock {} ({}).N)r   r    r!   r"   r   r   r   r   r&   Q   s   r&   c               @   s   e Zd ZdZdS )	NotLockedz/Failed to release the lock {} (was not locked).N)r   r    r!   r"   r   r   r   r   r'   U   s   r'   c               @   s   e Zd ZdZdS )	NotMyLockz=Failed to release the lock {} (was/is locked, but not by me).N)r   r    r!   r"   r   r   r   r   r(   Y   s   r(   c               @   sl   e Zd ZdZdddZdd Zdd	 Zd
d ZdddZdd Z	dd Z
dd Zdd Zdd Zdd ZdS )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).
    NFc             C   sP   || _ || _tjj|| _|p$tj | _tjj| jd| j | _	|| _
d| _d S )Nz%s.%d-%xF)r   r   ospathabspathr   get_process_ididjoinunique_namekill_stale_locksstale_warning_printed)r   r+   r   r   r.   r1   r   r   r   r   h   s    zExclusiveLock.__init__c             C   s   | j  S )N)acquire)r   r   r   r   	__enter__q   s    zExclusiveLock.__enter__c             G   s   | j   d S )N)release)r   excr   r   r   __exit__t   s    zExclusiveLock.__exit__c             C   s   d| j j| jf S )Nz<%s: %r>)r   r   r0   )r   r   r   r   r   w   s    zExclusiveLock.__repr__c             C   s   |d kr| j }|d kr| j}t||j }xytj| j W nl tk
rv   | j rX| S | j	  |j
 rrt| jY q, tk
r } zt| jt|d W Y d d }~X q,X t| jd W d Q R X | S q,W d S )Nwb)r   r   r   r   r*   mkdirr+   FileExistsErrorby_mekill_stale_lockr   r%   OSErrorr&   stropenr0   )r   r   r   timererrr   r   r   r3   z   s&    $
zExclusiveLock.acquirec             C   s@   | j  st| j| j s$t| jtj| j tj| j d S )N)		is_lockedr'   r+   r;   r(   r*   unlinkr0   rmdir)r   r   r   r   r5      s    

zExclusiveLock.releasec             C   s   t jj| jS )N)r*   r+   exists)r   r   r   r   rB      s    zExclusiveLock.is_lockedc             C   s   t jj| jS )N)r*   r+   rE   r0   )r   r   r   r   r;      s    zExclusiveLock.by_mec       
   "   C   s  yt j| j}W n tk
r$   dS X x|D  ]}y4|jdd\}}|jdd\}}t|}t|}W n$ tk
r   tjd|| j dS X t	j
|||rdS | js| jstjd| d| _dS y&t jt jj| j| tjd| W q. tk
r* }	 z$| jstjd	|t|	 d| _dS d }	~	X q.X q.W yt j| j W nD tk
r }	 z&|	jtjkrfdS tjd
t|	 dS d }	~	X nX dS )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.TzKilled stale lock %s.z0Found stale lock %s, but cannot delete due to %szFailed to remove lock dir: %s)r*   listdirr+   FileNotFoundErrorrsplitintr   loggererrorr   process_aliver1   r2   warningrC   r/   r=   r>   rD   errnoZ	ENOTEMPTY)
r   namesnameZhost_pidZ
thread_strhostZpid_strpidthreadrA   r   r   r   r<      sH    zExclusiveLock.kill_stale_lockc             C   sD   | j  r@x*tj| jD ]}tjtjj| j| qW tj| j d S )N)rB   r*   rH   r+   rC   r/   rD   )r   rR   r   r   r   
break_lock   s    zExclusiveLock.break_lockc          
   C   sf   | j |ksttjj| jd| }| j rT| j rTt|d W dQ R X tj| j	 || | _ | _	dS )z0migrate the lock ownership from old_id to new_idz%s.%d-%xr8   N)
r.   AssertionErrorr*   r+   r/   rB   r;   r?   rC   r0   )r   old_idnew_idZnew_unique_namer   r   r   migrate_lock   s    
zExclusiveLock.migrate_lock)NNNF)NN)r   r    r!   r"   r   r4   r7   r   r3   r5   rB   r;   r<   rV   rZ   r   r   r   r   r)   ]   s   

	
2r)   c               @   sR   e Zd ZdZd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S )
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.
    NFc             C   s   || _ |ptj | _|| _d S )N)r+   r   r-   r.   r1   )r   r+   r.   r1   r   r   r   r      s    zLockRoster.__init__c       	      C   s   yt | j}tj|}W d Q R X | jrxttfD ]}y|| }W n tk
rX   w2Y nX t }xD|D ]<\}}}t	j
|||r|j|||f qftjd|||| qfW t|||< q2W W n ttfk
r   i }Y nX |S )Nz:Removed stale %s roster lock for host %s pid %d thread %d.)r?   r+   jsonloadr1   SHARED	EXCLUSIVEKeyErrorsetr   rN   r   rL   rO   listrI   r   )	r   fdatakeyZentrieselementsrS   rT   rU   r   r   r   r]      s&    
zLockRoster.loadc          
   C   s(   t | jd}tj|| W d Q R X d S )Nw)r?   r+   r\   dump)r   rd   rc   r   r   r   save  s    zLockRoster.savec             C   s*   yt j| j W n tk
r$   Y nX d S )N)r*   rC   r+   rI   )r   r   r   r   r   
  s    zLockRoster.removec             C   s"   | j  }tdd |j|g D S )Nc             s   s   | ]}t |V  qd S )N)tuple).0er   r   r   	<genexpr>  s    z!LockRoster.get.<locals>.<genexpr>)r]   ra   get)r   re   rosterr   r   r   rn     s    zLockRoster.getc                s   t  fdd|D S )Nc             3   s   | ]} j | V  qd S )N)rn   )rk   re   )r   r   r   rm     s    z#LockRoster.empty.<locals>.<genexpr>)all)r   keysr   )r   r   empty  s    zLockRoster.emptyc             C   s   | j  }ytdd || D }W n tk
r<   t }Y nX |tkrT|j| j n8|tkrj|j| j n"|tkr|j	| j nt
d| tdd |D ||< | j| d S )Nc             s   s   | ]}t |V  qd S )N)rj   )rk   rl   r   r   r   rm     s    z$LockRoster.modify.<locals>.<genexpr>zUnknown LockRoster op %rc             s   s   | ]}t |V  qd S )N)rb   )rk   rl   r   r   r   rm   (  s    )r]   ra   r`   ADDr   r.   REMOVEdiscardREMOVE2r   r   rb   ri   )r   re   opro   rf   r   r   r   modify  s    zLockRoster.modifyc             C   sl   | j |kst| jd }| _zBy| j|t W n tk
rH   || _ Y nX || _ | j|t W d|| _X dS )z0migrate the lock ownership from old_id to new_idFN)r.   rW   r1   rx   rv   r`   rs   )r   re   rX   rY   Zkillingr   r   r   rZ   +  s    zLockRoster.migrate_lock)NF)r   r    r!   r"   r   r]   ri   r   rn   rr   rx   rZ   r   r   r   r   r[      s   
r[   c               @   st   e Zd ZdZdddZdd Zdd	 Zd
d Zd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S )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).
    FNc             C   sT   || _ || _|| _|| _|p"tj | _t|d ||d| _t	|d |||d| _
d S )Nz.roster)r.   r1   z
.exclusive)r.   r   r1   )r+   is_exclusiver   r   r   r-   r.   r[   _rosterr)   _lock)r   r+   r   r   r   r.   r1   r   r   r   r   N  s    zLock.__init__c             C   s   | j  S )N)r3   )r   r   r   r   r4   [  s    zLock.__enter__c             G   s   | j   d S )N)r5   )r   r6   r   r   r   r7   ^  s    zLock.__exit__c             C   s   d| j j| jf S )Nz<%s: %r>)r   r   r.   )r   r   r   r   r   a  s    zLock.__repr__c          
   C   s|   |d kr| j }|p| jpd}|r<| j|| | jjtt n6| j* |d k	rZ| jj|t | jjt	t W d Q R X || _ | S )Ng?)
rz   r   _wait_for_readers_finishingr{   rx   r_   rs   r|   rt   r^   )r   r   r   r   r   r   r   r3   d  s    zLock.acquirec          	   C   s   t | j|j }x| jj  yH|d k	r4| jj|t t| jj	t
dkrLd S |d k	rb| jj|t W n   | jj   Y nX | jj  |j rt| jqW d S )Nr   )r   r   r   r|   r3   r{   rx   rt   lenrn   r^   rs   r5   r   r%   r+   )r   r   r   r@   r   r   r   r}   s  s     


z Lock._wait_for_readers_finishingc          
   C   st   | j r8| jjtt | jjttr,| jj  | jj	  n8| j, | jjtt | jjttrf| jj  W d Q R X d S )N)
rz   r{   rx   r_   rt   rr   r^   r   r|   r5   )r   r   r   r   r5     s    
zLock.releasec             C   s   | j s| jdtd d S )NT)r   r   )rz   r3   r^   )r   r   r   r   upgrade  s    zLock.upgradec             C   s   | j r| jdtd d S )NF)r   r   )rz   r3   r_   )r   r   r   r   	downgrade  s    zLock.downgradec             C   s   | j o| jj o| jj S )N)rz   r|   rB   r;   )r   r   r   r   got_exclusive_lock  s    zLock.got_exclusive_lockc             C   s   | j j  | jj  d S )N)r{   r   r|   rV   )r   r   r   r   rV     s    
zLock.break_lockc             C   sn   | j |kst|| _ | jr:| jj|| | jjt|| n0| j$ | jj|| | jjt|| W d Q R X d S )N)r.   rW   rz   r|   rZ   r{   r_   r^   )r   rX   rY   r   r   r   rZ     s    zLock.migrate_lock)FNNNF)NNN)r   r    r!   r"   r   r4   r7   r   r3   r}   r5   r   r   r   rV   rZ   r   r   r   r   ry   ?  s   

ry   )r   r   r	   )r
   r   )rP   r\   r*   r    r   Zhelpersr   r   rL   r   rs   rt   rv   r^   r_   r   r   r#   r$   r%   r&   r'   r(   r)   r[   ry   r   r   r   r   <module>   s(   
5 ^