
    Je|                      
   d Z eZddlZddlZddlmZ ddlmZ ddl	m
Z
 d ZddlmZ ej                  dk(  sdd	lmZ dd
lmZ ddlmZ ddlmZ dZn!dZddlZddlmZ dZdZd Zd ZeZd Zd Zd Z G d d      Zd ZddgZy)a  
Filesystem-based interprocess mutex.

Taken from the Twisted project.
Distributed under the MIT (Expat) license.

Changes by the Spyder Team to the original module:
  * Rewrite kill Windows function to make it more reliable.
  * Detect if the process that owns the lock is an Spyder one.

Adapted from src/twisted/python/lockfile.py of the
`Twisted project <https://github.com/twisted/twisted>`_.
    N)time)to_binary_string)is_spyder_processc                  @    t        t        t               dz              S )Ni  )strint_uniquefloat     @/usr/lib/python3/dist-packages/spyder/utils/external/lockfile.pyuniquer   !   s    s<>D()**r   )renament)kill)symlink)readlink)removeFT)wintypesi   i  c                 <   t         j                  j                  }|j                  t        d|       }|dk(  ryt        j                         }|j                  |t        j                  |            }|dk(  }|j                  |       |xs |j                  t        k(  S )z/Taken from https://www.madebuild.org/blog/?p=30r   F)ctypeswindllkernel32OpenProcessPROCESS_QUERY_INFORMATIONr   DWORDGetExitCodeProcessbyrefCloseHandlevalueSTILL_ACTIVE)pidr   handle	exit_coderetval
is_runnings         r   _is_pid_runningr&   8   s    ==))%%&?CHQ; NN$	,,V-3\\)-DFk
V$ <Y__<<r   c                 N    t        |       st        t        j                  d       y N)r&   OSErrorerrnoESRCH)r!   signals     r   r   r   K   s    s#%++t,,r   c                    |dz   t               z   dz   }t        j                  j                  |d      }t        j                  |       t        |d      }|j                  t        |              |j                          |j                          	 t        ||       y #  	 t        j                  |       t        j                  |        # t        t        f$ r Y Y y w xY wxY w)N.z.newlinkr   wb)r   ospathjoinmkdir_openwriter   flushcloser   r   rmdirIOErrorr)   )r   filenamenewlinkname
newvalnamefs        r   r   r   T   s    sl68+J6WW\\+y9

*d#	 '(					;)				*%%  W% s0   B C! *C
C!CC!CC!c                 |   	 t        t        j                  j                  | d      d      }|j	                         j                         }|j                          |S # t        $ rV}|j                  t        j                  k(  s|j                  t        j                  k(  rt        |j                  d        d }~ww xY w)Nr   rb)r4   r0   r1   r2   readdecoder7   r9   r*   ENOENTEIOr)   )r:   fObjresultes       r   r   r   i   s    		h	:DAD YY['')FJJLM  	ww%,,&!''UYY*>aggt,,	s   *A 	B;%AB66B;c                     t        j                  t         j                  j                  | d             t        j                  |        y )Nr   )r0   r   r1   r2   r8   )r:   s    r   rmlinkrH   u   s)    
		"'',,x34
r   c                   *    e Zd ZdZdZdZd Zd Zd Zy)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                     || _         y r(   )name)selfrL   s     r   __init__zFilesystemLock.__init__   s	    	r   c                 (   d}	 	 t        t        t        j                               | j                         d| _        || _        y# t
        $ r}t        r1|j                  t        j                  t        j                  fv rY d}~y|j                  t        j                  k(  rg	 t        | j                        }nq# t
        $ r,}|j                  t        j                  k(  r	Y d}~Y d}~ d}~wt        $ r2}t        r&|j                  t        j                  k(  r	Y d}~Y d}~y d}~ww xY w	 t        t        t        |      d       t!        t        |            st        t        j"                  d      n# t
        $ r}|j                  t        j"                  k(  r`	 t%        | j                         n=# t
        $ r1}|j                  t        j                  k(  rY d}~Y d}~Y d}~ d}~ww xY wd}Y d}~Y d}~ d}~ww xY wY d}~y d}~ww xY w)z
        Acquire this lock.

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

        @raise: Any exception os.symlink() may raise, other than
        EEXIST.
        TNFr   zNo such process)r   r   r0   getpidrL   r)   _windowsr*   EACCESrC   EEXISTr   rB   r9   r   r   r   r+   rH   lockedclean)rM   rU   rF   r!   s       r   lockzFilesystemLock.lock   s    0BIIK($))4` DKDJc  .ELL%))+D D !77ell*&tyy1" 77ell2 %H" #5<<(? $)5+ S1-0S:")%++7H"IJ  ;" 77ekk1& &tyy 1#* &#$77ell#: %-H %& %*E$H  !].s   1A 
H2HH%B;:H;	D)C+!H*C++D)7#D$H#D$$D))H-A	E76H7	H G>F43G>4	G.=G)G>H(G))G..G>3H=G>>HHHHc                     t        | j                        }t        |      t        j                         k7  rt        d| j                  d      t        | j                         d| _        y)z
        Release this lock.

        This deletes the directory with the given name.

        @raise: Any exception os.readlink() may raise, or
        ValueError if the lock is not owned by this process.
        zLock z not owned by this processFN)r   rL   r   r0   rP   
ValueErrorrH   rT   )rM   r!   s     r   unlockzFilesystemLock.unlock   sI     tyy!s8ryy{"DIIOPPtyyr   )	__name__
__module____qualname____doc__rU   rT   rN   rV   rY   r
   r   r   rJ   rJ   {   s#    $ EF?Br   rJ   c                     t        |       }d}	 |j                         }|r|j                          | S # |r|j                          w w xY w)zDetermine 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)rJ   rV   rY   )rL   lrE   s      r   isLockedr`      sL     	tAFHHJ: HHJ s	   4 A	r`   )r]   type__metaclass__r*   r0   r   r	   spyder.py3compatr   spyder.utils.programsr   r   r   rL   r   r   r   r   rH   rQ   r   r   r   r    r&   openr4   rJ   r`   __all__r
   r   r   <module>rg      s      % - 3+ 	ww$#HH !& L=& E*
g gT& Z
(r   