localrepo: prevent wlock from being inherited when a transaction is running
authorSiddharth Agarwal <sid0@fb.com>
Tue, 06 Oct 2015 13:19:05 -0700
changeset 26499 e72b62b154b0
parent 26498 e8564e04382d
child 26500 5bd7c4c07f6d
localrepo: prevent wlock from being inherited when a transaction is running Review feedback from Pierre-Yves David. A separate line of work is working to ensure that dirstate writes are written to a separate 'pending' file while a transaction is active. Lock inheritance currently conflicts with that, so dodge the issue by simply preventing inheritance while a transaction is running. Custom merge drivers aren't going to run inside a transaction, so this doesn't affect that.
mercurial/localrepo.py
tests/test-lock.py
--- a/mercurial/localrepo.py	Tue Oct 06 13:13:31 2015 -0700
+++ b/mercurial/localrepo.py	Tue Oct 06 13:19:05 2015 -0700
@@ -1212,7 +1212,7 @@
             ce.refresh()
 
     def _lock(self, vfs, lockname, wait, releasefn, acquirefn, desc,
-              parentenvvar=None):
+              inheritchecker=None, parentenvvar=None):
         parentlock = None
         # the contents of parentenvvar are used by the underlying lock to
         # determine whether it can be inherited
@@ -1221,6 +1221,7 @@
         try:
             l = lockmod.lock(vfs, lockname, 0, releasefn=releasefn,
                              acquirefn=acquirefn, desc=desc,
+                             inheritchecker=inheritchecker,
                              parentlock=parentlock)
         except error.LockHeld as inst:
             if not wait:
@@ -1265,6 +1266,11 @@
         self._lockref = weakref.ref(l)
         return l
 
+    def _wlockchecktransaction(self):
+        if self.currenttransaction() is not None:
+            raise error.LockInheritanceContractViolation(
+                'wlock cannot be inherited in the middle of a transaction')
+
     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.
@@ -1296,7 +1302,9 @@
 
         l = self._lock(self.vfs, "wlock", wait, unlock,
                        self.invalidatedirstate, _('working directory of %s') %
-                       self.origroot, parentenvvar='HG_WLOCK_LOCKER')
+                       self.origroot,
+                       inheritchecker=self._wlockchecktransaction,
+                       parentenvvar='HG_WLOCK_LOCKER')
         self._wlockref = weakref.ref(l)
         return l
 
--- a/tests/test-lock.py	Tue Oct 06 13:13:31 2015 -0700
+++ b/tests/test-lock.py	Tue Oct 06 13:19:05 2015 -0700
@@ -260,7 +260,7 @@
         state.assertacquirecalled(True)
 
         def tryinherit():
-            with lock.inherit() as lockname:
+            with lock.inherit():
                 pass
 
         self.assertRaises(error.LockInheritanceContractViolation, tryinherit)