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']