##// END OF EJS Templates
lock: turn prepinherit/reacquire into a single context manager...
Siddharth Agarwal -
r26473:5f94e64f default
parent child Browse files
Show More
@@ -7,6 +7,7 b''
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
@@ -171,19 +172,20 b' class lock(object):'
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):
177 """context for the lock to be inherited by a Mercurial subprocess.
176
178
177 Returns a string that will be recognized by the lock in the
179 Yields a string that will be recognized by the lock in the subprocess.
178 subprocess. Communicating this string to the subprocess needs to be done
180 Communicating this string to the subprocess needs to be done separately
179 separately -- typically by an environment variable.
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:
@@ -191,12 +193,9 b' class lock(object):'
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:
198 raise error.LockInheritanceContractViolation(
199 'reacquire can only be called after prepinherit')
200 if self.acquirefn:
199 if self.acquirefn:
201 self.acquirefn()
200 self.acquirefn()
202 self._inherited = False
201 self._inherited = False
@@ -158,7 +158,7 b' class testlock(unittest.TestCase):'
158 parentstate.assertacquirecalled(True)
158 parentstate.assertacquirecalled(True)
159
159
160 # set up lock inheritance
160 # set up lock inheritance
161 lockname = parentlock.prepinherit()
161 with parentlock.inherit() as lockname:
162 parentstate.assertreleasecalled(True)
162 parentstate.assertreleasecalled(True)
163 parentstate.assertpostreleasecalled(False)
163 parentstate.assertpostreleasecalled(False)
164 parentstate.assertlockexists(True)
164 parentstate.assertlockexists(True)
@@ -167,14 +167,13 b' class testlock(unittest.TestCase):'
167 childlock = childstate.makelock(parentlock=lockname)
167 childlock = childstate.makelock(parentlock=lockname)
168 childstate.assertacquirecalled(True)
168 childstate.assertacquirecalled(True)
169
169
170 # release the child lock -- the lock file should still exist on disk
171 childlock.release()
170 childlock.release()
172 childstate.assertreleasecalled(True)
171 childstate.assertreleasecalled(True)
173 childstate.assertpostreleasecalled(True)
172 childstate.assertpostreleasecalled(True)
174 childstate.assertlockexists(True)
173 childstate.assertlockexists(True)
175
174
176 parentstate.resetacquirefn()
175 parentstate.resetacquirefn()
177 parentlock.reacquire()
176
178 parentstate.assertacquirecalled(True)
177 parentstate.assertacquirecalled(True)
179
178
180 parentlock.release()
179 parentlock.release()
@@ -188,7 +187,7 b' class testlock(unittest.TestCase):'
188 lock0 = state0.makelock()
187 lock0 = state0.makelock()
189 state0.assertacquirecalled(True)
188 state0.assertacquirecalled(True)
190
189
191 lock0name = lock0.prepinherit()
190 with lock0.inherit() as lock0name:
192 state0.assertreleasecalled(True)
191 state0.assertreleasecalled(True)
193 state0.assertpostreleasecalled(False)
192 state0.assertpostreleasecalled(False)
194 state0.assertlockexists(True)
193 state0.assertlockexists(True)
@@ -198,8 +197,9 b' class testlock(unittest.TestCase):'
198 state1.assertacquirecalled(True)
197 state1.assertacquirecalled(True)
199
198
200 # from within lock1, acquire another lock
199 # from within lock1, acquire another lock
201 lock1name = lock1.prepinherit()
200 with lock1.inherit() as lock1name:
202 # since the file on disk is lock0's this should have the same name
201 # since the file on disk is lock0's this should have the same
202 # name
203 self.assertEqual(lock0name, lock1name)
203 self.assertEqual(lock0name, lock1name)
204
204
205 state2 = teststate(self, d, pidoffset=2)
205 state2 = teststate(self, d, pidoffset=2)
@@ -212,7 +212,7 b' class testlock(unittest.TestCase):'
212 state2.assertlockexists(True)
212 state2.assertlockexists(True)
213
213
214 state1.resetacquirefn()
214 state1.resetacquirefn()
215 lock1.reacquire()
215
216 state1.assertacquirecalled(True)
216 state1.assertacquirecalled(True)
217
217
218 lock1.release()
218 lock1.release()
@@ -220,7 +220,6 b' class testlock(unittest.TestCase):'
220 state1.assertpostreleasecalled(True)
220 state1.assertpostreleasecalled(True)
221 state1.assertlockexists(True)
221 state1.assertlockexists(True)
222
222
223 lock0.reacquire()
224 lock0.release()
223 lock0.release()
225
224
226 def testinheritlockfork(self):
225 def testinheritlockfork(self):
@@ -230,7 +229,7 b' class testlock(unittest.TestCase):'
230 parentstate.assertacquirecalled(True)
229 parentstate.assertacquirecalled(True)
231
230
232 # set up lock inheritance
231 # set up lock inheritance
233 lockname = parentlock.prepinherit()
232 with parentlock.inherit() as lockname:
234 childstate = teststate(self, d, pidoffset=1)
233 childstate = teststate(self, d, pidoffset=1)
235 childlock = childstate.makelock(parentlock=lockname)
234 childlock = childstate.makelock(parentlock=lockname)
236 childstate.assertacquirecalled(True)
235 childstate.assertacquirecalled(True)
@@ -249,7 +248,6 b' class testlock(unittest.TestCase):'
249 childstate.assertpostreleasecalled(True)
248 childstate.assertpostreleasecalled(True)
250 childstate.assertlockexists(True)
249 childstate.assertlockexists(True)
251
250
252 parentlock.reacquire()
253 parentlock.release()
251 parentlock.release()
254
252
255 if __name__ == '__main__':
253 if __name__ == '__main__':
General Comments 0
You need to be logged in to leave comments. Login now