[PATCH RFC] lock-checker: new contrib extension based on work done by Mads
Augie Fackler
raf at durin42.com
Thu Aug 2 16:57:51 CDT 2012
# HG changeset patch
# User Augie Fackler <raf at durin42.com>
# Date 1343877207 18000
# Branch stable
# Node ID 496649db5432bedf0a454d091a24e73bb61c9ef8
# Parent e15765c18ebc18448addb955d2b698c75fc8b380
lock-checker: new contrib extension based on work done by Mads
This makes it possible to do lock validation as part of a normal test
run. I didn't attempt any wlock validation because that's a bit more
subtle to detect properly. Thanks to the initial patch from Mads for
the idea.
diff --git a/contrib/lock-checker.py b/contrib/lock-checker.py
new file mode 100644
--- /dev/null
+++ b/contrib/lock-checker.py
@@ -0,0 +1,48 @@
+"""Extension to verify locks are obtained in the required places.
+
+This works by wrapping functions that should be surrounded by a lock
+and asserting the lock is held. Missing locks are called out with a
+traceback printed to stderr.
+
+This currently only checks store locks, not working copy locks.
+"""
+import os
+import traceback
+
+def _warnstack(ui, msg, skip=1):
+ '''issue warning with the message and the current stack, skipping the
+ skip last entries'''
+ ui.warn('%s at:\n' % msg)
+ entries = traceback.extract_stack()[:-skip]
+ fnmax = max(len(entry[0]) for entry in entries)
+ for fn, ln, func, _text in entries:
+ ui.warn(' %*s:%-4s in %s\n' % (fnmax, fn, ln, func))
+
+def _checklock(repo):
+ l = repo._lockref and repo._lockref()
+ if l is None or not l.held:
+ _warnstack(repo.ui, 'missing lock', skip=2)
+
+def reposetup(ui, repo):
+ orig = repo.__class__
+ class lockcheckrepo(repo.__class__):
+ def _writejournal(self, *args, **kwargs):
+ _checklock(self)
+ return orig._writejournal(self, *args, **kwargs)
+
+ def transaction(self, *args, **kwargs):
+ _checklock(self)
+ return orig.transaction(self, *args, **kwargs)
+
+ # TODO(durin42): kiilerix had a commented-out lock check in
+ # writebranchcache and _writerequirements
+
+ def _tag(self, *args, **kwargs):
+ _checklock(self)
+ return orig._tag(self, *args, **kwargs)
+
+ def write(self, *args, **kwargs):
+ assert os.path.lexists(self._join('.hg/wlock'))
+ return orig.write(self, *args, **kwargs)
+
+ repo.__class__ = lockcheckrepo
More information about the Mercurial-devel
mailing list