changeset 24821:57f1dbc99631 stable

afterlock: add the callback to the top level lock (issue4608) If 'wlock' is taken, we should add 'afterlock' callback to the 'wlock' instead. Otherwise, running post transaction hook after 'lock' is release but 'wlock' is still taken lead to a deadlock (eg: 'hg update' during a hook). This situation is much more common since: 5dc5cd7abbf5 push: acquire local 'wlock' if "pushback" is expected (BC) (issue4596)
author Pierre-Yves David <pierre-yves.david@fb.com>
date Mon, 20 Apr 2015 15:27:55 +0200
parents 6a6b69d9e539
children 8678b1eafbcf
files mercurial/localrepo.py tests/test-hook.t
diffstat 2 files changed, 11 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/localrepo.py	Mon Apr 20 16:05:32 2015 +0200
+++ b/mercurial/localrepo.py	Mon Apr 20 15:27:55 2015 +0200
@@ -1194,13 +1194,16 @@
         return l
 
     def _afterlock(self, callback):
-        """add a callback to the current repository lock.
+        """add a callback to be run when the repository is fully unlocked
 
-        The callback will be executed on lock release."""
-        l = self._lockref and self._lockref()
-        if l:
-            l.postrelease.append(callback)
-        else:
+        The callback will be executed when the outermost lock is released
+        (with wlock being higher level than 'lock')."""
+        for ref in (self._wlockref, self._lockref):
+            l = ref and ref()
+            if l and l.held:
+                l.postrelease.append(callback)
+                break
+        else: # no lock have been found.
             callback()
 
     def lock(self, wait=True):
--- a/tests/test-hook.t	Mon Apr 20 16:05:32 2015 +0200
+++ b/tests/test-hook.t	Mon Apr 20 15:27:55 2015 +0200
@@ -1,4 +1,5 @@
 commit hooks can see env vars
+(and post-transaction one are run unlocked)
 
   $ hg init a
   $ cd a
@@ -16,6 +17,7 @@
   > pretxnclose = sh -c "HG_LOCAL= HG_TAG= python \"$TESTDIR/printenv.py\" pretxnclose"
   > txnclose = sh -c "HG_LOCAL= HG_TAG= python \"$TESTDIR/printenv.py\" txnclose"
   > txnabort = sh -c "HG_LOCAL= HG_TAG= python \"$TESTDIR/printenv.py\" txnabort"
+  > txnclose.checklock = hg debuglock > /dev/null
   > EOF
   $ echo a > a
   $ hg add a