# HG changeset patch # User Tomasz Kleczek # Date 2012-09-27 21:38:03 # Node ID 829919ef894acb189c8ec0431e59f36338eb038f # Parent 07d577dae285bf7effafc68aab55220f4acdad0e 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. diff --git a/mercurial/lock.py b/mercurial/lock.py --- a/mercurial/lock.py +++ b/mercurial/lock.py @@ -97,7 +97,12 @@ class lock(object): 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: