B
    lz]                 @   s   d Z ddlmZmZmZmZ ddlmZ ddlZddlZddl	m
Z
mZmZmZmZ ddlZddlmZ ddlmZ d	Zd
ZeeZedZdddZG dd deZG dd deZeZdS )aP  
Tools for working with locks

A lock is just an empty directory. We use directories because this lets us use
the race condition-proof os.makedirs.

For now, there is one global lock for all of conda, because some things happen
globally (such as downloading packages).

We don't raise an error if the lock is named with the current PID
    )absolute_importdivisionprint_functionunicode_literals)globN)abspathbasenamedirnameisdirjoin   )range)	LockErrorZ
conda_lockz
LOCKERROR: It looks like conda is already doing something.
The lock {0} was found. Wait for it to finish before continuing.
If you are sure that conda is not running, remove it and try again.
You can also use: $ conda clean --lock
zconda.stdoutlogc          
   C   s`   y&t | d t| | W dQ R X W n4 ttfk
rZ } ztd|j W dd}~X Y nX dS )z Touch function like touch in Unix shell
    :param file_name: the name of file
    :param times: the access and modified time
    Examples:
        touch("hello_world.py")
    aNzHFailed to create lock, do not run conda in parallel processes [errno %d])openosutimeOSErrorIOErrorlogwarnerrno)	file_nametimese r   )lib/python3.7/site-packages/conda/lock.pytouch(   s    r   c               @   s*   e Zd ZdZd
ddZdd Zdd Zd	S )FileLockzLock a path (file or directory) with the lock file sitting *beside* path.

    :param path_to_lock: the path to be locked
    :param retries: max number of retries
    
   c             C   sf   t || _|| _d| jtf | _d| jtf | _tt| jsNtd	| jd| jksbt| jdS )z	
        z%s.pid{0}.%sz
%s.pid*.%sz{0} doesn't existz::N)
r   path_to_lockretriesLOCK_EXTENSIONlock_file_pathlock_file_glob_strr
   r	   AssertionErrorformat)selfr    r!   r   r   r   __init__=   s    
zFileLock.__init__c             C   s   d}| j t | _ d }xjt| jd D ]X}t| j}|rtt	t
| t	d| t|d  |d9 }|}q*t| j  | S q*W td tt
|d S )Nr   zSleeping for %s secondsr      zExceeded max retries, giving up)r#   r&   r   getpidr   r!   r   r$   r   debugLOCKSTRtimeZsleepr   	stdoutlogerrorr   )r'   Z
sleep_timeZlast_glob_match_Zglob_resultr   r   r   	__enter__H   s    


zFileLock.__enter__c             C   s   ddl m} || j d S )Nr   )rm_rf)Zgateways.disk.deleter2   r#   )r'   exc_type	exc_value	tracebackr2   r   r   r   __exit___   s    zFileLock.__exit__N)r   )__name__
__module____qualname____doc__r(   r1   r6   r   r   r   r   r   7   s   
r   c               @   s   e Zd ZdZdddZdS )DirectoryLocka  Lock a directory with the lock file sitting *within* the directory being locked.

    Useful when, for example, locking the root prefix at ``/conda``, and ``/`` is not writable.

    :param directory_path: the path to be locked
    :param retries: max number of retries
    r   c          
   C   s   t || _t| j}|| _t| j|}d|tf | _d|tf | _tt	| js`t
d| jt| jsyt| j td| j W n8 ttfk
r } ztd| j|j W d d }~X Y nX d S )Nz%s.pid{0}.%sz
%s.pid*.%sz{0} doesn't existzforced to create %sz(Failed to create directory %s [errno %d])r   directory_pathr   r!   r   r"   r#   r$   r
   r	   r%   r&   r   makedirsr   r+   r   r   r   r   )r'   r<   r!   Zdirectory_nameZlock_path_prer   r   r   r   r(   n   s    


zDirectoryLock.__init__N)r   )r7   r8   r9   r:   r(   r   r   r   r   r;   e   s   r;   )N)r:   Z
__future__r   r   r   r   r   Zloggingr   os.pathr   r   r	   r
   r   r-   Zcommon.compatr   
exceptionsr   r"   r,   Z	getLoggerr7   r   r.   r   objectr   r;   ZLockedr   r   r   r   <module>   s    	


.