Patchwork [2,of,5] lock: add a way to prevent locks from being inherited

login
register
mail settings
Submitter Siddharth Agarwal
Date Oct. 6, 2015, 11:40 p.m.
Message ID <d790c5c34f0e0693a90e.1444174804@dev6666.prn1.facebook.com>
Download mbox | patch
Permalink /patch/10839/
State Accepted
Headers show

Comments

Siddharth Agarwal - Oct. 6, 2015, 11:40 p.m.
# HG changeset patch
# User Siddharth Agarwal <sid0@fb.com>
# Date 1444162411 25200
#      Tue Oct 06 13:13:31 2015 -0700
# Node ID d790c5c34f0e0693a90e99773f48f9a8b04f14b2
# Parent  83230ffce268ede1151ed17ddf4ec773fd7bfb24
lock: add a way to prevent locks from being inherited

We want to prevent locks from being inherited sometimes (e.g. when there's a
currently running transaction, which will break a lot of assumptions we're
making in here.)

Patch

diff --git a/mercurial/lock.py b/mercurial/lock.py
--- a/mercurial/lock.py
+++ b/mercurial/lock.py
@@ -40,7 +40,7 @@  class lock(object):
     _host = None
 
     def __init__(self, vfs, file, timeout=-1, releasefn=None, acquirefn=None,
-                 desc=None, parentlock=None):
+                 desc=None, inheritchecker=None, parentlock=None):
         self.vfs = vfs
         self.f = file
         self.held = 0
@@ -48,6 +48,7 @@  class lock(object):
         self.releasefn = releasefn
         self.acquirefn = acquirefn
         self.desc = desc
+        self._inheritchecker = inheritchecker
         self.parentlock = parentlock
         self._parentheld = False
         self._inherited = False
@@ -186,6 +187,8 @@  class lock(object):
         if self._inherited:
             raise error.LockInheritanceContractViolation(
                 'inherit cannot be called while lock is already inherited')
+        if self._inheritchecker:
+            self._inheritchecker()
         if self.releasefn:
             self.releasefn()
         if self._parentheld:
diff --git a/tests/test-lock.py b/tests/test-lock.py
--- a/tests/test-lock.py
+++ b/tests/test-lock.py
@@ -8,6 +8,7 @@  import types
 import unittest
 
 from mercurial import (
+    error,
     lock,
     scmutil,
 )
@@ -250,5 +251,21 @@  class testlock(unittest.TestCase):
 
         parentlock.release()
 
+    def testinheritcheck(self):
+        d = tempfile.mkdtemp(dir=os.getcwd())
+        state = teststate(self, d)
+        def check():
+            raise error.LockInheritanceContractViolation('check failed')
+        lock = state.makelock(inheritchecker=check)
+        state.assertacquirecalled(True)
+
+        def tryinherit():
+            with lock.inherit() as lockname:
+                pass
+
+        self.assertRaises(error.LockInheritanceContractViolation, tryinherit)
+
+        lock.release()
+
 if __name__ == '__main__':
     silenttestrunner.main(__name__)