lock-checker.py
48 lines
| 1.6 KiB
| text/x-python
|
PythonLexer
/ contrib / lock-checker.py
Augie Fackler
|
r17669 | """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 | ||||