U
    ̋_                     @   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  ejejdZeejedZeejedZejdZeejedZeeje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 | | || _|| _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 held 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   r   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 r   )r   r   r   r   r   locked>   s    zFileLock.lockedc                 C   sF   | j r| j S t| 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  d| _ dS )zRelase the lock.N)r   oscloser   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  zt | d}W n tk
r$   Y dS X tdtjtjddd}t|tj|}t	d|d }zzt d| dv}zHdd | D D ]0\}}|d	kr|   W W  5 Q R  W W \S qW n& tk
r   Y W 5 Q R  W W 4dS X W 5 Q R X W n tk
r
   Y W 
dS X W 5 |
  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   | ]}| 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unpackr   	readlinesstripr   )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   sH   z$t tttfD ]} | js|   q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r2   r   r   r   r      s    r   c                  C   s@   t tttfD ]} |   qztjd= W n tk
r:   Y nX dS )z<Release an exclusive lock for the package management system.r4   N)r8   r7   r6   r5   r   r   r9   KeyErrorr:   r   r   r   r      s    
r   c              
      s    fdd}z r    nt   W n tk
r } zjd_tj_|jrbd}||j _t	
d|}jrjst	   qnt	| jrt W 5 d}~X Y 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                      s:   z r    nt   W n tk
r.   Y 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   r<   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   wait_for_lock   s"    



rD   )N)"r   
__author____all__r+   r   r*   r   Zgi.repositoryr   Z	aptdaemonr   Zaptdaemon.errorsr   r   r   objectr   r   Zinitr   dirnameZconfigZ	find_fileZ_status_dirjoinr6   r5   Zfind_dirZ_archives_dirr7   r8   r   r   rD   r   r   r   r   <module>   s2   !
 