Thanks for pushing Sylvain changes Jed. I got a terrible flu this weekend so I couldn't do any Spyder related job =)

Sylvain, I'm attaching a new lockfile.py incorporating the changes of the blog post you referenced. Could you try it and tell us if it's working for you? I tested it in my local machines and it's doing its job as before.

Cheers,
Carlos

El 15/04/13 12:45, Jed Ludlow escribió:
On Sunday, April 14, 2013 8:32:18 PM UTC-6, Sylvain Corlay wrote:

    No pb, I can test your changes when you have it.
    Good luck with the last lap before the final release.
    Best,
    Sylvain


Not trying to steal Carlos's thunder, but I had a little bit of time over the weekend to look at the the "run selection" behavior and the debug toolbar issues. I just pushed a couple of changes that should solve them. If you find any additional issues with the changes, please open up an issue on the tracker.

Jed
--
You received this message because you are subscribed to the Google Groups "spyder" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/spyderlib?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.



--
You received this message because you are subscribed to the Google Groups 
"spyder" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/spyderlib?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.


# Copyright (c) 2005 Divmod, Inc.
# Copyright (c) Twisted Matrix Laboratories.
# Twisted is distributed under the MIT license.

"""
Filesystem-based interprocess mutex.
"""

__metaclass__ = type

import errno, os

from time import time as _uniquefloat

def unique():
    return str(long(_uniquefloat() * 1000))

from os import rename
if not os.name == 'nt':
    from os import kill
    from os import symlink
    from os import readlink
    from os import remove as rmlink
    _windows = False
else:
    _windows = True

    try:
        import ctypes
        from ctypes import wintypes
    except ImportError:
        kill = None   #analysis:ignore
    else:
        # GetExitCodeProcess uses a special exit code to indicate that the
        # process is still running.
        STILL_ACTIVE = 259
        
        def _is_pid_running(pid):
            kernel32 = ctypes.windll.kernel32
            handle = kernel32.OpenProcess(1, 0, pid)
            if handle == 0:
                return False
             
            # If the process exited recently, a pid may still exist for the
            # handle. So, check if we can get the exit code.
            exit_code = wintypes.DWORD()
            retval = kernel32.GetExitCodeProcess(handle,
                                                 ctypes.byref(exit_code))
            is_running = (retval == 0)
            kernel32.CloseHandle(handle)
             
            # See if we couldn't get the exit code or the exit code indicates
            # that the process is still running.
            return is_running or exit_code.value == STILL_ACTIVE

        def kill(pid, signal):
            if not _is_pid_running(pid):
                raise OSError(errno.ESRCH, None)
            else:
                return
            
    _open = file

    # XXX Implement an atomic thingamajig for win32
    def symlink(value, filename):    #analysis:ignore
        newlinkname = filename+"."+unique()+'.newlink'
        newvalname = os.path.join(newlinkname,"symlink")
        os.mkdir(newlinkname)
        f = _open(newvalname,'wcb')
        f.write(value)
        f.flush()
        f.close()
        try:
            rename(newlinkname, filename)
        except:
            os.remove(newvalname)
            os.rmdir(newlinkname)
            raise

    def readlink(filename):   #analysis:ignore
        try:
            fObj = _open(os.path.join(filename,'symlink'), 'rb')
        except IOError, e:
            if e.errno == errno.ENOENT or e.errno == errno.EIO:
                raise OSError(e.errno, None)
            raise
        else:
            result = fObj.read()
            fObj.close()
            return result

    def rmlink(filename):    #analysis:ignore
        os.remove(os.path.join(filename, 'symlink'))
        os.rmdir(filename)



class FilesystemLock:
    """
    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.
    """

    clean = None
    locked = False

    def __init__(self, name):
        self.name = name


    def lock(self):
        """
        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.
        """
        clean = True
        while True:
            try:
                symlink(str(os.getpid()), self.name)
            except OSError, e:
                if _windows and e.errno in (errno.EACCES, errno.EIO):
                    # The lock is in the middle of being deleted because we're
                    # on Windows where lock removal isn't atomic.  Give up, we
                    # don't know how long this is going to take.
                    return False
                if e.errno == errno.EEXIST:
                    try:
                        pid = readlink(self.name)
                    except OSError, e:
                        if e.errno == errno.ENOENT:
                            # The lock has vanished, try to claim it in the
                            # next iteration through the loop.
                            continue
                        raise
                    except IOError, e:
                        if _windows and e.errno == errno.EACCES:
                            # The lock is in the middle of being
                            # deleted because we're on Windows where
                            # lock removal isn't atomic.  Give up, we
                            # don't know how long this is going to
                            # take.
                            return False
                        raise
                    try:
                        if kill is not None:
                            kill(int(pid), 0)
                    except OSError, e:
                        if e.errno == errno.ESRCH:
                            # The owner has vanished, try to claim it in the next
                            # iteration through the loop.
                            try:
                                rmlink(self.name)
                            except OSError, e:
                                if e.errno == errno.ENOENT:
                                    # Another process cleaned up the lock.
                                    # Race them to acquire it in the next
                                    # iteration through the loop.
                                    continue
                                raise
                            clean = False
                            continue
                        raise
                    return False
                raise
            self.locked = True
            self.clean = clean
            return True


    def unlock(self):
        """
        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.
        """
        pid = readlink(self.name)
        if int(pid) != os.getpid():
            raise ValueError("Lock %r not owned by this process" % (self.name,))
        rmlink(self.name)
        self.locked = False


def isLocked(name):
    """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.
    """
    l = FilesystemLock(name)
    result = None
    try:
        result = l.lock()
    finally:
        if result:
            l.unlock()
    return not result


__all__ = ['FilesystemLock', 'isLocked']

Reply via email to