3
_                 @   s  d Z dZdZ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
 ddlmZ G d	d deZG d
d deZdd Zej  ejjejjdZeejjedZeejjedZejjdZeejjedZeejjejjddZdd Zdd Z dddZ!dS )zHandles the apt system lockz%Sebastian Heinlein <devel@glatzor.de>LockFailedErrorsystem    N)GLib)enums)TransactionCancelledc               @   s   e Zd ZdZdddZdS )r   zThe locking of file failed.Nc             C   s4   d| }|r|d| 7 }t j| | || _|| _dS )zReturn a new LockFailedError instance.

        Keyword arguments:
        flock -- the path of the file lock
        process -- the process which holds the lock or None
        zCould not acquire lock on %s.z The lock is hold by %s.N)	Exception__init__flockprocess)selfr	   r
   msg r   0/usr/lib/python3/dist-packages/aptdaemon/lock.pyr   '   s    zLockFailedError.__init__)N)__name__
__module____qualname____doc__r   r   r   r   r   r   #   s   c               @   s4   e Zd ZdZdd Zedd Zdd Zdd	 Zd
S )FileLockzRepresents a file lock.c             C   s   || _ d | _d S )N)pathfd)r   r   r   r   r   r   :   s    zFileLock.__init__c             C   s
   | j d k	S )N)r   )r   r   r   r   locked>   s    zFileLock.lockedc             C   sF   | j r| j S tj| j}|dk r8t| j}t| j|n
|| _ |S dS )zuReturn the file descriptor of the lock file or raise
        LockFailedError if the lock cannot be obtained.
        r   N)r   apt_pkgZget_lockr   get_locking_process_namer   )r   Zfd_lockr
   r   r   r   acquireB   s    
zFileLock.acquirec             C   s   | j rtj| j  d| _ dS )zRelase the lock.N)r   osclose)r   r   r   r   releaseP   s    zFileLock.releaseN)	r   r   r   r   r   propertyr   r   r   r   r   r   r   r   6   s
   r   c          &   C   s   yt | d}W n tk
r"   dS X tjdtjtjddd}tj|tj|}tj	d|d }zyht d| dP}y4x.dd |j
 D D ]\}}|d	kr|j S qW W n tk
r   dS X W dQ R X W n tk
r   dS X W d|j  X dS )
zjReturn the name of a process which holds a lock. It will be None if
    the name cannot be retrivied.
    rNZhhQQir      z/proc/%s/statusc             s   s   | ]}|j d V  qdS ):N)split).0liner   r   r   	<genexpr>h   s    z+get_locking_process_name.<locals>.<genexpr>Name)openIOErrorstructZpackfcntlZF_WRLCKr   SEEK_SETZF_GETLKZunpack	readlinesstripr   r   )Z	lock_pathZfd_lock_readZflkZflk_retpidZ	fd_statuskeyvaluer   r   r   r   W   s(    

r   zDir::State::statuslockzlock-frontendzDir::Cache::ArchiveszDir::State::listsc           
   C   sL   y(x"t tttfD ]} | js| j  qW W n   t   Y nX dtjd< dS )z<Acquire an exclusive lock for the package management system.1DPKG_FRONTEND_LOCKEDN)	frontend_lockstatus_lockarchive_lock
lists_lockr   r   r   r   environ)r0   r   r   r   r      s    r   c              C   sD   xt tttfD ]} | j  qW ytjd= W n tk
r>   Y nX dS )z<Release an exclusive lock for the package management system.r2   N)r6   r5   r4   r3   r   r   r7   KeyError)r0   r   r   r   r      s    r   c                s    fdd}y r j   nt   W n tk
r } zrd_tj_|jrbjd}||j _t	j
d|}xjrj rt	j j  qpW t	j| jrt W Y dd}~X nX dS )zAcquire the system lock or the optionally given one. If the lock
    cannot be obtained pause the transaction in the meantime.

    :param trans: the transaction
    :param lock: optional alternative lock
    c                  s8   y r j   nt   W n tk
r,   dS X d_dS )zHelper to unpause the transaction if the lock can be obtained.

        Keyword arguments:
        trans -- the corresponding transaction
        alt_lock -- alternative lock to the system lock
        TF)r   r   pausedr   )alt_locktransr   r   
watch_lock   s    

z!wait_for_lock.<locals>.watch_lockTzWaiting for %s to exit   N)r   r   r9   r   ZSTATUS_WAITING_LOCKZstatusr
   gettextZstatus_detailsr   Ztimeout_add_secondsZ	cancelledZmain_context_defaultZ	iterationZsource_remover   )r;   r:   r<   errorr   Z
lock_watchr   )r:   r;   r   wait_for_lock   s"    



r@   )r   r   )N)"r   
__author____all__r)   r   r(   r   Zgi.repositoryr   Z	aptdaemonr   Zaptdaemon.errorsr   r   r   objectr   r   Zinitr   dirnameconfigZ	find_fileZ_status_dirjoinr4   r3   Zfind_dirZ_archives_dirr5   r6   r   r   r@   r   r   r   r   <module>   s.   !