[PATCH 3 of 3 fyi] hack: more lock validation, checking opener usage
Mads Kiilerich
mads at kiilerich.com
Sun Nov 17 17:53:59 UTC 2013
# HG changeset patch
# User Mads Kiilerich <mads at kiilerich.com>
# Date 1326756353 -3600
# Tue Jan 17 00:25:53 2012 +0100
# Branch stable
# Node ID cc7c104ed113b1a221ab4898ef1a7b7fe294f881
# Parent ca1828f0c90d81978daa555fdcdbe841d4fe70b3
hack: more lock validation, checking opener usage
This revealed too many problems and was thus put in a separate patch so they
could be ignored.
diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -162,13 +162,19 @@ class localrepository(object):
return self.requirements[:]
def __init__(self, baseui, path=None, create=False):
- self.wvfs = scmutil.vfs(path, expandpath=True, realpath=True)
+ def lockverify(fn):
+ #print repr(fn)
+ if '/store/' in fn or '/journal.' in fn:
+ self.checklock(skip=3)
+ else:
+ self.checkwlock(skip=3)
+ self.wvfs = scmutil.vfs(path, expandpath=True, realpath=True, lockverify=lambda dirname: self.checkwlock(skip=3))
self.wopener = self.wvfs
self.root = self.wvfs.base
self.path = self.wvfs.join(".hg")
self.origroot = path
self.auditor = scmutil.pathauditor(self.root, self._checknested)
- self.vfs = scmutil.vfs(self.path)
+ self.vfs = scmutil.vfs(self.path, lockverify=lockverify)
self.opener = self.vfs
self.baseui = baseui
self.ui = baseui.copy()
@@ -192,6 +198,8 @@ class localrepository(object):
else:
self.supported = self._basesupported
+ self._transref = self._lockref = self._wlockref = None
+
if not self.vfs.isdir():
if create:
if not self.wvfs.exists():
@@ -205,7 +213,7 @@ class localrepository(object):
requirements.append("fncache")
if self.ui.configbool('format', 'dotencode', True):
requirements.append('dotencode')
- # create an invalid changelog
+ # create an invalid changelog WITHOUT LOCKING!
self.vfs.append(
"00changelog.i",
'\0\0\0\2' # represents revlogv2
@@ -249,7 +257,6 @@ class localrepository(object):
self._branchcaches = {}
self.filterpats = {}
self._datafilters = {}
- self._transref = self._lockref = self._wlockref = None
# A cache for various files under .hg/ that tracks file changes,
# (used by the filecache decorator)
@@ -268,7 +275,11 @@ class localrepository(object):
self._applyrequirements(requirements)
if create:
- self._writerequirements()
+ try:
+ wlock = self.wlock()
+ self._writerequirements()
+ finally:
+ wlock.release()
def close(self):
pass
@@ -1075,6 +1086,7 @@ class localrepository(object):
ui.warnstack('trying to unlock wlock with lock held',
skip=1)
+ self.checkwlock()
self.dirstate.write()
self._filecache['dirstate'].refresh()
diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py
--- a/mercurial/scmutil.py
+++ b/mercurial/scmutil.py
@@ -293,11 +293,12 @@ class vfs(abstractvfs):
This class is used to hide the details of COW semantics and
remote file access from higher level code.
'''
- def __init__(self, base, audit=True, expandpath=False, realpath=False):
+ def __init__(self, base, audit=True, expandpath=False, realpath=False, lockverify=None):
if expandpath:
base = util.expandpath(base)
if realpath:
base = os.path.realpath(base)
+ self.lockverify = lockverify
self.base = base
self._setmustaudit(audit)
self.createmode = None
@@ -341,6 +342,8 @@ class vfs(abstractvfs):
nlink = -1
if mode not in ('r', 'rb'):
+ if self.lockverify:
+ self.lockverify(f)
dirname, basename = util.split(f)
# If basename is empty, then the path is malformed because it points
# to a directory. Let the posixfile() call below raise IOError.
diff --git a/mercurial/tags.py b/mercurial/tags.py
--- a/mercurial/tags.py
+++ b/mercurial/tags.py
@@ -15,6 +15,7 @@ from i18n import _
import encoding
import error
import errno
+import lock as lockmod
def findglobaltags(ui, repo, alltags, tagtypes):
'''Find global tags in repo by reading .hgtags from every head that
@@ -256,6 +257,10 @@ def _readtagcache(ui, repo):
return (repoheads, cachefnode, None, True)
def _writetagcache(ui, repo, heads, tagfnode, cachetags):
+ wlock = lock = None
+ try:
+ wlock = repo.wlock()
+ lock = repo.lock()
try:
cachefile = repo.opener('cache/tags', 'w', atomictemp=True)
@@ -298,3 +303,6 @@ def _writetagcache(ui, repo, heads, tagf
cachefile.close()
except (OSError, IOError):
pass
+
+ finally:
+ lockmod.release(lock, wlock)
More information about the Mercurial-devel
mailing list