[PATCH RFC] lock-checker: new contrib extension based on work done by Mads

Mads Kiilerich mads at kiilerich.com
Wed Sep 12 18:04:55 CDT 2012


Augie Fackler wrote, On 09/13/2012 12:47 AM:
> Friendly ping? Should I consider resending this?

This cleanup of my original hack did - for good reasons - leave out some 
of the most ugly parts of my original hack. These ugly parts did however 
exist for a reason. So I will keep my ugly patch in my queue and use 
that occasionally, and I don't care much whether this goes to contrib or 
not.

But I guess this extension could have some value if it was used by one 
of the buildbots - is that a part of the plan?

Anyway, the warnstack code has been useful for debugging other stuff 
too. It could perhaps be included in ui.py or some more low-level library.

/Mads


> On Aug 2, 2012, at 4:57 PM, Augie Fackler wrote:
>
>> # 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
>> _______________________________________________
>> Mercurial-devel mailing list
>> Mercurial-devel at selenic.com
>> http://selenic.com/mailman/listinfo/mercurial-devel
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel at selenic.com
> http://selenic.com/mailman/listinfo/mercurial-devel



More information about the Mercurial-devel mailing list