##// END OF EJS Templates
Make revrange return a list of ints so that callers don't have to convert
Make revrange return a list of ints so that callers don't have to convert

File last commit:

r2859:345bac2b default
r3526:68341c06 default
Show More
lock.py
118 lines | 3.7 KiB | text/x-python | PythonLexer
mpm@selenic.com
Simply repository locking...
r161 # lock.py - simple locking scheme for mercurial
#
Vadim Gelfer
update copyrights.
r2859 # Copyright 2005, 2006 Matt Mackall <mpm@selenic.com>
mpm@selenic.com
Simply repository locking...
r161 #
# This software may be used and distributed according to the terms
# of the GNU General Public License, incorporated herein by reference.
Vadim Gelfer
make lock module use demandload.
r1836 from demandload import *
Vadim Gelfer
change lock format to let us detect and break stale locks....
r1877 demandload(globals(), 'errno os socket time util')
mpm@selenic.com
Simply repository locking...
r161
Vadim Gelfer
fix backtrace printed when cannot get lock....
r2016 class LockException(IOError):
def __init__(self, errno, strerror, filename, desc):
IOError.__init__(self, errno, strerror, filename)
self.desc = desc
Benoit Boissinot
Raise a different exception when the lock is not available...
r1753 class LockHeld(LockException):
Vadim Gelfer
fix backtrace printed when cannot get lock....
r2016 def __init__(self, errno, filename, desc, locker):
LockException.__init__(self, errno, 'Lock held', filename, desc)
self.locker = locker
Benoit Boissinot
Raise a different exception when the lock is not available...
r1753 class LockUnavailable(LockException):
mpm@selenic.com
Simply repository locking...
r161 pass
Eric Hopper
Convert all classes to new-style classes by deriving them from object.
r1559 class lock(object):
Vadim Gelfer
change lock format to let us detect and break stale locks....
r1877 # lock is symlink on platforms that support it, file on others.
# symlink is used because create of directory entry and contents
# are atomic even over nfs.
# old-style lock: symlink to pid
# new-style lock: symlink to hostname:pid
Vadim Gelfer
fix backtrace printed when cannot get lock....
r2016 def __init__(self, file, timeout=-1, releasefn=None, desc=None):
mpm@selenic.com
Simply repository locking...
r161 self.f = file
self.held = 0
Benoit Boissinot
add a timeout when a lock is held (default 1024 sec)...
r1787 self.timeout = timeout
Benoit Boissinot
add a releasefn keyword to lock.lock...
r1530 self.releasefn = releasefn
Vadim Gelfer
change lock format to let us detect and break stale locks....
r1877 self.id = None
self.host = None
self.pid = None
Vadim Gelfer
fix backtrace printed when cannot get lock....
r2016 self.desc = desc
mpm@selenic.com
Simply repository locking...
r161 self.lock()
def __del__(self):
self.release()
def lock(self):
Benoit Boissinot
add a timeout when a lock is held (default 1024 sec)...
r1787 timeout = self.timeout
mpm@selenic.com
Simply repository locking...
r161 while 1:
try:
self.trylock()
return 1
except LockHeld, inst:
Benoit Boissinot
add a timeout when a lock is held (default 1024 sec)...
r1787 if timeout != 0:
mpm@selenic.com
Simply repository locking...
r161 time.sleep(1)
Benoit Boissinot
add a timeout when a lock is held (default 1024 sec)...
r1787 if timeout > 0:
timeout -= 1
mpm@selenic.com
Simply repository locking...
r161 continue
Vadim Gelfer
fix backtrace printed when cannot get lock....
r2016 raise LockHeld(errno.ETIMEDOUT, inst.filename, self.desc,
inst.locker)
mpm@selenic.com
Whitespace cleanups...
r515
mpm@selenic.com
Simply repository locking...
r161 def trylock(self):
Vadim Gelfer
change lock format to let us detect and break stale locks....
r1877 if self.id is None:
self.host = socket.gethostname()
self.pid = os.getpid()
self.id = '%s:%s' % (self.host, self.pid)
while not self.held:
try:
util.makelock(self.id, self.f)
self.held = 1
except (OSError, IOError), why:
if why.errno == errno.EEXIST:
locker = self.testlock()
if locker:
Vadim Gelfer
fix backtrace printed when cannot get lock....
r2016 raise LockHeld(errno.EAGAIN, self.f, self.desc,
locker)
Vadim Gelfer
change lock format to let us detect and break stale locks....
r1877 else:
Vadim Gelfer
fix backtrace printed when cannot get lock....
r2016 raise LockUnavailable(why.errno, why.strerror,
why.filename, self.desc)
Vadim Gelfer
change lock format to let us detect and break stale locks....
r1877
def testlock(self):
'''return id of locker if lock is valid, else None.'''
# if old-style lock, we cannot tell what machine locker is on.
# with new-style lock, if locker is on this machine, we can
# see if locker is alive. if locker is on this machine but
# not alive, we can safely break lock.
locker = util.readlock(self.f)
Benoit Boissinot
use __contains__, index or split instead of str.find...
r2579 try:
host, pid = locker.split(":", 1)
except ValueError:
Vadim Gelfer
change lock format to let us detect and break stale locks....
r1877 return locker
if host != self.host:
return locker
mpm@selenic.com
Simply repository locking...
r161 try:
Benoit Boissinot
use __contains__, index or split instead of str.find...
r2579 pid = int(pid)
Vadim Gelfer
change lock format to let us detect and break stale locks....
r1877 except:
return locker
if util.testpid(pid):
return locker
# if locker dead, break lock. must do this with another lock
# held, or can race and break valid lock.
try:
l = lock(self.f + '.break')
l.trylock()
os.unlink(self.f)
l.release()
except (LockHeld, LockUnavailable):
return locker
mpm@selenic.com
Simply repository locking...
r161
def release(self):
if self.held:
self.held = 0
Benoit Boissinot
add a releasefn keyword to lock.lock...
r1530 if self.releasefn:
self.releasefn()
mpm@selenic.com
Fix troubles with clone and exception handling...
r503 try:
os.unlink(self.f)
except: pass
mpm@selenic.com
Simply repository locking...
r161