ó
‹²,]c           @   sd  d  Z  e Z d d l Z d d l Z d d l m Z d d l Z d d l m	 Z	 d d l
 m Z 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 e Z na e 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 d d d „  ƒ  YZ d „  Z  d d g Z! d S(   sŽ  
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>`_.
iÿÿÿÿN(   t   time(   t   running_under_pytest(   t   PY2t   to_binary_stringc           C   s8   t  r t t t ƒ  d ƒ ƒ St t t ƒ  d ƒ ƒ Sd  S(   Niè  (   R   t   strt   longt   _uniquefloatt   int(    (    (    s=   lib/python2.7/site-packages/spyder/utils/external/lockfile.pyt   unique"   s    (   t   renamet   nt(   t   kill(   t   symlink(   t   readlink(   t   remove(   t   wintypesi   i  c         C   s„   t  j j } | j t d |  ƒ } | d k r1 t St j ƒ  } | j | t  j	 | ƒ ƒ } | d k } | j
 | ƒ | pƒ | j t k S(   s/   Taken from https://www.madebuild.org/blog/?p=30i    (   t   ctypest   windllt   kernel32t   OpenProcesst   PROCESS_QUERY_INFORMATIONt   FalseR   t   DWORDt   GetExitCodeProcesst   byreft   CloseHandlet   valuet   STILL_ACTIVE(   t   pidR   t   handlet	   exit_codet   retvalt
   is_running(    (    s=   lib/python2.7/site-packages/spyder/utils/external/lockfile.pyt   _is_pid_running<   s    	c         C   s)   t  |  ƒ s! t t j d  ƒ ‚ n d  Sd  S(   N(   R!   t   OSErrort   errnot   ESRCHt   None(   R   t   signal(    (    s=   lib/python2.7/site-packages/spyder/utils/external/lockfile.pyR   O   s    c         C   sÈ   | d t  ƒ  d } t j j | d ƒ } t j | ƒ t | d ƒ } | j t |  ƒ ƒ | j ƒ  | j	 ƒ  y t
 | | ƒ WnC y t j | ƒ t j | ƒ Wn t t f k
 r¼ d  SX‚  n Xd  S(   Nt   .s   .newlinkR   t   wb(   R   t   ost   patht   joint   mkdirt   _opent   writeR   t   flusht   closeR	   R   t   rmdirt   IOErrorR"   (   R   t   filenamet   newlinknamet
   newvalnamet   f(    (    s=   lib/python2.7/site-packages/spyder/utils/external/lockfile.pyR   X   s     

c         C   s˜   y" t  t j j |  d ƒ d ƒ } WnO t k
 rs } | j t j k sX | j t j k rm t | j d  ƒ ‚ n  ‚  n! X| j
 ƒ  j ƒ  } | j ƒ  | Sd  S(   NR   t   rb(   R-   R)   R*   R+   R2   R#   t   ENOENTt   EIOR"   R%   t   readt   decodeR0   (   R3   t   fObjt   et   result(    (    s=   lib/python2.7/site-packages/spyder/utils/external/lockfile.pyR   m   s    "$
c         C   s-   t  j t  j j |  d ƒ ƒ t  j |  ƒ d  S(   NR   (   R)   R   R*   R+   R1   (   R3   (    (    s=   lib/python2.7/site-packages/spyder/utils/external/lockfile.pyt   rmlinky   s    t   FilesystemLockc           B   s5   e  Z d  Z d Z e Z d „  Z d „  Z d „  Z	 RS(   s  
    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.
    c         C   s   | |  _  d  S(   N(   t   name(   t   selfRA   (    (    s=   lib/python2.7/site-packages/spyder/utils/external/lockfile.pyt   __init__•   s    c         C   sL  t  } x?t  rGy  t t t j ƒ  ƒ |  j ƒ Wnÿt k
 r0} t rf | j t j	 t j
 f k rf t S| j t j k r*y t |  j ƒ } Wn_ t k
 r» } | j t j k rµ q	 n  ‚  n2 t k
 rì } t ræ | j t j	 k ræ t S‚  n XyÀ t d k	 rt t | ƒ d ƒ n  t j t | ƒ ƒ } t d d d d d d g ƒ } t ƒ  r^| j d ƒ n  t d	 „  | j ƒ  d
  Dƒ ƒ } | | @g } t | ƒ s¬t t j d ƒ ‚ n  Wnv t k
 r%} | j t j k ry t |  j ƒ Wn. t k
 r} | j t j k rq	 n  ‚  n Xt } q	 n  ‚  n Xt S‚  n Xt  |  _ | |  _ t  SWd S(   sÏ   
        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.
        i    t   spydert   spyder3s
   spyder.exes   spyder3.exes   bootstrap.pys   spyder-script.pys   runtests.pyc         s   s!   |  ] } t  j j | ƒ Vq d  S(   N(   R)   R*   t   basename(   t   .0t   arg(    (    s=   lib/python2.7/site-packages/spyder/utils/external/lockfile.pys	   <genexpr>Í   s   i   s   No such processN(   t   TrueR   R   R)   t   getpidRA   R"   t   _windowsR#   t   EACCESR9   R   t   EEXISTR   R8   R2   R   R%   R   t   psutilt   Processt   setR   t   addt   cmdlinet   anyR$   R?   t   lockedt   clean(   RB   RU   R=   R   t   pt   namest	   argumentst
   conditions(    (    s=   lib/python2.7/site-packages/spyder/utils/external/lockfile.pyt   lock˜   s`    
	 !				c         C   sZ   t  |  j ƒ } t | ƒ t j ƒ  k r@ t d |  j f ƒ ‚ n  t |  j ƒ t |  _ d S(   sÕ   
        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.
        s!   Lock %r not owned by this processN(	   R   RA   R   R)   RJ   t
   ValueErrorR?   R   RT   (   RB   R   (    (    s=   lib/python2.7/site-packages/spyder/utils/external/lockfile.pyt   unlockè   s
    	N(
   t   __name__t
   __module__t   __doc__R%   RU   R   RT   RC   RZ   R\   (    (    (    s=   lib/python2.7/site-packages/spyder/utils/external/lockfile.pyR@      s   		Pc         C   s>   t  |  ƒ } d } z | j ƒ  } Wd | r8 | j ƒ  n  X| S(   sÚ   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(   R@   R%   RZ   R\   (   RA   t   lR>   (    (    s=   lib/python2.7/site-packages/spyder/utils/external/lockfile.pyt   isLockedø   s    	Ra   (    ("   R_   t   typet   __metaclass__R#   R)   R    R   RN   t   spyder.config.baseR   t   spyder.py3compatR   R   R   R	   RA   R   R   R   R   R?   R   RK   RI   R   R   R   R   R!   t   openR-   R@   Ra   t   __all__(    (    (    s=   lib/python2.7/site-packages/spyder/utils/external/lockfile.pyt   <module>   s8   							y	