o
    bZ                     @   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	 s3ddlm
Z
mZmZmZ d	Zn0d
ZzddlZddlmZ W n eyL   dZ
Y n	w 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   9/usr/lib/python3/dist-packages/twisted/python/lockfile.pyunique   s   r	   )rename)killreadlinkremovesymlinkFT)OpenProcess   W   c              
   C   sj   zt dd|  W t	d tjy4 } z|jd tkr"W Y d }~d S |jd tkr/ttjd  d }~ww )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 d   n1 s0w   Y  zt|| W dS  t	yO   t
| t|  w )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filenamenewlinkname
newvalnamemodefr   r   r   r   E   s   




r   c              
   C   s   zt tj| dd}W n ty+ } z|jtjks |jtjkr&t|jd d}~ww | | }W d   |S 1 s>w   Y  |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*   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   r5   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)selfr7   r   r   r   __init__   s   
zFilesystemLock.__init__c                 C   s  d}	 zt tt | j W n ty } ztr)|jtjtj	fv r)W Y d}~dS |jtj
krzt| j}W n2 tyh } z&|jtjkrOW Y d}~W Y d}~qtrc|jtjkrcW Y d}~W Y d}~dS  d}~ww ztdurutt|d W nK ty } z?|jtjkrzt| j W n# ty } z|jtjkrW Y d}~W Y d}~W Y d}~q d}~ww d}W Y d}~W Y d}~q d}~ww W Y d}~dS  d}~ww 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}.
        TNFr   )r   r   r    getpidr7   r   _windowsr   EACCESr1   EEXISTr   r0   r   r   r   r5   lockedclean)r8   r?   r   r   r   r   r   lock   sX   
 +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   r7   r   r    r:   
ValueErrorr5   r>   )r8   r   r   r   r   unlock   s
   
	

zFilesystemLock.unlock)	__name__
__module____qualname____doc__r?   r>   r9   r@   rB   r   r   r   r   r6   w   s    =r6   c                 C   s:   t | }d}z| }W |r|  | S |r|  w w )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)r6   r@   rB   )r7   lr4   r   r   r   isLocked   s   


rH   )rF   r   r    r   r   twisted.python.runtimer   r	   r
   	isWindowsr   r   r   r5   r   r;   r   win32apir   ImportErrorr   r   openr$   r6   rH   __all__r   r   r   r   <module>   s6   f