made repo locks recursive and deprecate refcounting based lock releasing
all locks should use the explicit lock.release
mercurial.lock.lock.__del__ handles unwrapping recursive locks
localrepo.lock/wlock are still using weakref in order to keep backward
compatibiltiy to releasing locks via garbage collection
by ensuring the release on __del__
--- a/mercurial/localrepo.py Wed Apr 22 01:53:15 2009 +0200
+++ b/mercurial/localrepo.py Wed Apr 22 02:01:22 2009 +0200
@@ -683,8 +683,10 @@
return l
def lock(self, wait=True):
- if self._lockref and self._lockref():
- return self._lockref()
+ l = self._lockref and self._lockref()
+ if l is not None and l.held:
+ l.lock()
+ return l
l = self._lock(self.sjoin("lock"), wait, None, self.invalidate,
_('repository %s') % self.origroot)
@@ -692,8 +694,10 @@
return l
def wlock(self, wait=True):
- if self._wlockref and self._wlockref():
- return self._wlockref()
+ l = self._wlockref and self._wlockref()
+ if l is not None and l.held:
+ l.lock()
+ return l
l = self._lock(self.join("wlock"), wait, self.dirstate.write,
self.dirstate.invalidate, _('working directory of %s') %
--- a/mercurial/lock.py Wed Apr 22 01:53:15 2009 +0200
+++ b/mercurial/lock.py Wed Apr 22 02:01:22 2009 +0200
@@ -27,6 +27,11 @@
self.lock()
def __del__(self):
+ if self.held:
+ # ensure the lock will be removed
+ # even if recursive locking did occur
+ self.held = 1
+
self.release()
def lock(self):
@@ -45,6 +50,9 @@
inst.locker)
def trylock(self):
+ if self.held:
+ self.held += 1
+ return
if lock._host is None:
lock._host = socket.gethostname()
lockname = '%s:%s' % (lock._host, os.getpid())
@@ -97,7 +105,9 @@
return locker
def release(self):
- if self.held:
+ if self.held > 1:
+ self.held -= 1
+ elif self.held is 1:
self.held = 0
if self.releasefn:
self.releasefn()
@@ -105,3 +115,8 @@
os.unlink(self.f)
except: pass
+def release(*locks):
+ for lock in locks:
+ if lock is not None:
+ lock.release()
+