comparison mercurial/lock.py @ 17682:829919ef894a stable

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.
author Tomasz Kleczek <tomasz.kleczek@fb.com>
date Thu, 27 Sep 2012 14:38:03 -0700
parents cc24e4ed3e0c
children 6d7db5794e8c
comparison
equal deleted inserted replaced
17678:07d577dae285 17682:829919ef894a
95 not alive, we can safely break lock. 95 not alive, we can safely break lock.
96 96
97 The lock file is only deleted when None is returned. 97 The lock file is only deleted when None is returned.
98 98
99 """ 99 """
100 locker = util.readlock(self.f) 100 try:
101 locker = util.readlock(self.f)
102 except OSError, why:
103 if why.errno == errno.ENOENT:
104 return None
105 raise
101 try: 106 try:
102 host, pid = locker.split(":", 1) 107 host, pid = locker.split(":", 1)
103 except ValueError: 108 except ValueError:
104 return locker 109 return locker
105 if host != lock._host: 110 if host != lock._host: