U
    c6{i*  ã                   @   sê   d Z ddlZddlZddlmZ ddlmZ dd„ ZddlmZ e 	¡ sfddlm
Z
mZmZmZ d	Znbd
ZzddlZddlmZ W n ek
rš   dZ
Y nX dZdZdd„ Z
eZdd„ Zdd„ Zdd„ ZG dd„ dƒZdd„ ZddgZdS )z&
Filesystem-based interprocess mutex.
é    N)Útime)Úplatformc                   C   s   t ttƒ d ƒƒS )Niè  )ÚstrÚintÚ_uniquefloat© r   r   ú;/tmp/pip-unpacked-wheel-hfbvu0bz/twisted/python/lockfile.pyÚunique   s    r	   )Úrename)ÚkillÚreadlinkÚremoveÚsymlinkFT)ÚOpenProcessé   éW   c              
   C   sv   zt dd| ƒ W nX tjk
rh } z8|jd tkr<W Y ¢$d S |jd tkrVttjd ƒ‚‚ W 5 d }~X Y n
X t	dƒ‚d S )Nr   z OpenProcess is required to fail.)
r   Ú
pywintypesÚerrorÚargsÚERROR_ACCESS_DENIEDÚERROR_INVALID_PARAMETERÚOSErrorÚerrnoÚESRCHÚRuntimeError)ÚpidÚsignalÚer   r   r   r   4   s    
r   c              	   C   s”   |d t ƒ  d }tj |d¡}t |¡ d}t||ƒ�}| | ¡ | ¡  W 5 Q R X zt||ƒ W n* t	k
rŽ   t 
|¡ t |¡ ‚ Y nX dS )zŠ
        Write a file at C{filename} with the contents of C{value}. See the
        above comment block as to why this is needed.
        Ú.z.newlinkr   ÚwN)r	   ÚosÚpathÚjoinÚmkdirÚ_openÚwriteÚflushr
   ÚBaseExceptionr   Úrmdir)ÚvalueÚfilenameZnewlinknameZ
newvalnameÚmodeÚfr   r   r   r   E   s    



r   c              
   C   s‚   zt tj | d¡dƒ}W nH tk
r` } z*|jtjksB|jtjkrNt|jdƒ‚‚ W 5 d}~X Y nX |� | ¡ }W 5 Q R X |S dS )zq
        Read the contents of C{filename}. See the above comment block as to why
        this is needed.
        r   ÚrN)	r$   r    r!   r"   r   r   ÚENOENTÚEIOÚread)r*   ZfObjr   Úresultr   r   r   r   `   s    r   c                 C   s"   t  t j | d¡¡ t  | ¡ d S )Nr   )r    r   r!   r"   r(   )r*   r   r   r   Úrmlinkr   s    r2   c                   @   s0   e Zd ZdZdZdZdd„ Zdd„ Zdd	„ ZdS )
ÚFilesystemLocka  
    A mutex.

    This relies on the filesystem property that creating
    a symlink is an atomic operation and that it will
    fail if the symlink already exists.  Deleting the
    symlink will release the lock.

    @ivar name: The name of the file associated with this lock.

    @ivar clean: Indicates whether this lock was released cleanly by its
        last owner.  Only meaningful after C{lock} has been called and
        returns True.

    @ivar locked: Indicates whether the lock is currently held by this
        object.
    NFc                 C   s
   || _ d S )N)Úname)Úselfr4   r   r   r   Ú__init__�   s    zFilesystemLock.__init__c                 C   s¾  d}zt tt ¡ ƒ| jƒ W �nŽ tk
�r¬ } �zltrV|jtjtj	fkrVW Y �¢NdS |jtj
k�ršzt| jƒ}W nb tk
rÔ } zD|jtjkr¢W Y ¢2W Y �¢qn trÂ|jtjkrÂW Y ¢W Y ¢âdS ‚ W 5 d}~X Y nX ztdk	rîtt|ƒdƒ W nž tk
�rŽ } z~|jtjk�r|zt| jƒ W nH tk
�rh } z(|jtjk�rVW Y ¢W Y ¢4W Y ¢Lq‚ W 5 d}~X Y nX d}W Y ¢W Y ¢&q‚ W 5 d}~X Y nX W Y ¢
dS ‚ W 5 d}~X Y nX d| _|| _dS )zç
        Acquire this lock.

        @rtype: C{bool}
        @return: True if the lock is acquired, false otherwise.

        @raise OSError: Any exception L{os.symlink()} may raise,
            other than L{errno.EEXIST}.
        TFNr   )r   r   r    Úgetpidr4   r   Ú_windowsr   ÚEACCESr/   ÚEEXISTr   r.   r   r   r   r2   ÚlockedÚclean)r5   r<   r   r   r   r   r   Úlock�   sD    

zFilesystemLock.lockc                 C   s@   t | jƒ}t|ƒt ¡ kr,td| j›d�ƒ‚t| jƒ d| _dS )zå
        Release this lock.

        This deletes the directory with the given name.

        @raise OSError: Any exception L{os.readlink()} may raise.
        @raise ValueError: If the lock is not owned by this process.
        zLock z not owned by this processFN)r   r4   r   r    r7   Ú
ValueErrorr2   r;   )r5   r   r   r   r   ÚunlockÍ   s
    	

zFilesystemLock.unlock)	Ú__name__Ú
__module__Ú__qualname__Ú__doc__r<   r;   r6   r=   r?   r   r   r   r   r3   w   s   =r3   c                 C   s.   t | ƒ}d}z| ¡ }W 5 |r&| ¡  X | S )zß
    Determine if the lock of the given name is held or not.

    @type name: C{str}
    @param name: The filesystem path to the lock to test

    @rtype: C{bool}
    @return: True if the lock is held, False otherwise.
    N)r3   r?   r=   )r4   Úlr1   r   r   r   ÚisLockedÝ   s    

rE   )rC   r   r    r   r   Ztwisted.python.runtimer   r	   r
   Z	isWindowsr   r   r   r2   r   r8   r   Úwin32apir   ÚImportErrorr   r   Úopenr$   r3   rE   Ú__all__r   r   r   r   Ú<module>   s2   
f