Patchwork [1,of,3,V2] devel: move the lock-checking code into core

login
register
mail settings
Submitter Pierre-Yves David
Date March 18, 2015, 11:47 p.m.
Message ID <9ca943457b05281a1dba.1426722475@marginatus.alto.octopoid.net>
Download mbox | patch
Permalink /patch/8155/
State Accepted
Commit d6ac30f4edefcf205bf27a3ddf37626922fa8018
Headers show

Comments

Pierre-Yves David - March 18, 2015, 11:47 p.m.
# HG changeset patch
# User Pierre-Yves David <pierre-yves.david@fb.com>
# Date 1421405470 28800
#      Fri Jan 16 02:51:10 2015 -0800
# Node ID 9ca943457b05281a1dba7fb78005b500ec5355ad
# Parent  5cb459dc32d209653a3e5d77749cf989ab9a51e4
devel: move the lock-checking code into core

If the developer warning are enabled, bad locking order will be reported without
the need for the contrib extensions.

Patch

diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -1187,10 +1187,19 @@  class localrepository(object):
 
     def wlock(self, wait=True):
         '''Lock the non-store parts of the repository (everything under
         .hg except .hg/store) and return a weak reference to the lock.
         Use this before modifying files in .hg.'''
+        if (self.ui.configbool('devel', 'all')
+                or self.ui.configbool('devel', 'check-locks')):
+            l = self._lockref and self._lockref()
+            if l is not None and l.held:
+                msg = '"lock" taken before "wlock"\n'
+                if self.ui.tracebackflag:
+                    util.debugstacktrace(msg, 1)
+                else:
+                    self.ui.write_err(msg)
         l = self._wlockref and self._wlockref()
         if l is not None and l.held:
             l.lock()
             return l
 
diff --git a/tests/test-devel-warnings.t b/tests/test-devel-warnings.t
new file mode 100644
--- /dev/null
+++ b/tests/test-devel-warnings.t
@@ -0,0 +1,49 @@ 
+
+  $ cat << EOF > buggylocking.py
+  > """A small extension to acquires lock in the wrong order
+  > """
+  > 
+  > from mercurial import cmdutil
+  > 
+  > cmdtable = {}
+  > command = cmdutil.command(cmdtable)
+  > 
+  > @command('buggylocking', [], '')
+  > def buggylocking(ui, repo):
+  >     lo = repo.lock()
+  >     wl = repo.wlock()
+  > EOF
+
+  $ cat << EOF >> $HGRCPATH
+  > [extensions]
+  > buggylocking=$TESTTMP/buggylocking.py
+  > [devel]
+  > all=1
+  > EOF
+
+  $ hg init lock-checker
+  $ cd lock-checker
+  $ hg buggylocking
+  "lock" taken before "wlock"
+  $ cat << EOF >> $HGRCPATH
+  > [devel]
+  > all=0
+  > check-locks=1
+  > EOF
+  $ hg buggylocking
+  "lock" taken before "wlock"
+  $ hg buggylocking --traceback
+  "lock" taken before "wlock"
+   at:
+   */hg:* in <module> (glob)
+   */mercurial/dispatch.py:* in run (glob)
+   */mercurial/dispatch.py:* in dispatch (glob)
+   */mercurial/dispatch.py:* in _runcatch (glob)
+   */mercurial/dispatch.py:* in _dispatch (glob)
+   */mercurial/dispatch.py:* in runcommand (glob)
+   */mercurial/dispatch.py:* in _runcommand (glob)
+   */mercurial/dispatch.py:* in checkargs (glob)
+   */mercurial/dispatch.py:* in <lambda> (glob)
+   */mercurial/util.py:* in check (glob)
+   $TESTTMP/buggylocking.py:* in buggylocking (glob)
+  $ cd ..