comparison mercurial/lock.py @ 26473:5f94e64f182c

lock: turn prepinherit/reacquire into a single context manager Review feedback from Pierre-Yves David. This makes the overall code cleaner and less error-prone, and makes a previously explicitly checked error state impossible.
author Siddharth Agarwal <sid0@fb.com>
date Sun, 04 Oct 2015 20:02:50 -0700
parents e16f80f89a29
children 431094a3b21f
comparison
equal deleted inserted replaced
26472:406a654b41cb 26473:5f94e64f182c
5 # This software may be used and distributed according to the terms of the 5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version. 6 # GNU General Public License version 2 or any later version.
7 7
8 from __future__ import absolute_import 8 from __future__ import absolute_import
9 9
10 import contextlib
10 import errno 11 import errno
11 import os 12 import os
12 import socket 13 import socket
13 import time 14 import time
14 import warnings 15 import warnings
169 170
170 """ 171 """
171 locker = self._readlock() 172 locker = self._readlock()
172 return self._testlock(locker) 173 return self._testlock(locker)
173 174
174 def prepinherit(self): 175 @contextlib.contextmanager
175 """prepare for the lock to be inherited by a Mercurial subprocess 176 def inherit(self):
176 177 """context for the lock to be inherited by a Mercurial subprocess.
177 Returns a string that will be recognized by the lock in the 178
178 subprocess. Communicating this string to the subprocess needs to be done 179 Yields a string that will be recognized by the lock in the subprocess.
179 separately -- typically by an environment variable. 180 Communicating this string to the subprocess needs to be done separately
181 -- typically by an environment variable.
180 """ 182 """
181 if not self.held: 183 if not self.held:
182 raise error.LockInheritanceContractViolation( 184 raise error.LockInheritanceContractViolation(
183 'prepinherit can only be called while lock is held') 185 'inherit can only be called while lock is held')
184 if self._inherited: 186 if self._inherited:
185 raise error.LockInheritanceContractViolation( 187 raise error.LockInheritanceContractViolation(
186 'prepinherit cannot be called while lock is already inherited') 188 'inherit cannot be called while lock is already inherited')
187 if self.releasefn: 189 if self.releasefn:
188 self.releasefn() 190 self.releasefn()
189 if self._parentheld: 191 if self._parentheld:
190 lockname = self.parentlock 192 lockname = self.parentlock
191 else: 193 else:
192 lockname = '%s:%s' % (lock._host, self.pid) 194 lockname = '%s:%s' % (lock._host, self.pid)
193 self._inherited = True 195 self._inherited = True
194 return lockname 196 try:
195 197 yield lockname
196 def reacquire(self): 198 finally:
197 if not self._inherited: 199 if self.acquirefn:
198 raise error.LockInheritanceContractViolation( 200 self.acquirefn()
199 'reacquire can only be called after prepinherit') 201 self._inherited = False
200 if self.acquirefn:
201 self.acquirefn()
202 self._inherited = False
203 202
204 def release(self): 203 def release(self):
205 """release the lock and execute callback function if any 204 """release the lock and execute callback function if any
206 205
207 If the lock has been acquired multiple times, the actual release is 206 If the lock has been acquired multiple times, the actual release is