Mercurial > public > mercurial-scm > hg-stable
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 |