lock: fixed race condition in trylock/testlock (issue3506) stable
authorTomasz Kleczek <tomasz.kleczek@fb.com>
Thu, 27 Sep 2012 14:38:03 -0700
branchstable
changeset 17682 829919ef894a
parent 17678 07d577dae285
child 17683 6d7db5794e8c
child 17696 b3f0f9a39c4e
lock: fixed race condition in trylock/testlock (issue3506) Suppose the following scenario: 1. Process A takes the lock (e.g. on commit). 2. Process B wants to grab the lock. Since lock file exists the exception is raised. In the catch block the testlock function is called. 3. Process A releases the lock. 4. Process B tries to read the lock file as a part of testlock function. This results in OSError (ENOENT) and since we're not inside the exception handler function this is propagated and aborts the whole operation. To fix this we now check in testlock function whether lock file actually exists and if not (i.e. if readlock fails) we just return.
mercurial/lock.py
--- a/mercurial/lock.py	Sat Sep 29 13:33:55 2012 +0200
+++ b/mercurial/lock.py	Thu Sep 27 14:38:03 2012 -0700
@@ -97,7 +97,12 @@
         The lock file is only deleted when None is returned.
 
         """
-        locker = util.readlock(self.f)
+        try:
+            locker = util.readlock(self.f)
+        except OSError, why:
+            if why.errno == errno.ENOENT:
+                return None
+            raise
         try:
             host, pid = locker.split(":", 1)
         except ValueError: