##// END OF EJS Templates
Duplicate cache when creating templater.
Duplicate cache when creating templater.

File last commit:

r1877:d314a89f default
r1975:6e1a8ea5 default
Show More
lock.py
108 lines | 3.1 KiB | text/x-python | PythonLexer
mpm@selenic.com
Simply repository locking...
r161 # lock.py - simple locking scheme for mercurial
#
# Copyright 2005 Matt Mackall <mpm@selenic.com>
#
# 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
Benoit Boissinot
Raise a different exception when the lock is not available...
r1753 class LockException(Exception):
pass
class LockHeld(LockException):
pass
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
Benoit Boissinot
add a timeout when a lock is held (default 1024 sec)...
r1787 def __init__(self, file, timeout=-1, releasefn=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
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
raise inst
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:
raise LockHeld(locker)
else:
raise LockUnavailable(why)
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)
c = locker.find(':')
if c == -1:
return locker
host = locker[:c]
if host != self.host:
return locker
mpm@selenic.com
Simply repository locking...
r161 try:
Vadim Gelfer
change lock format to let us detect and break stale locks....
r1877 pid = int(locker[c+1:])
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