##// END OF EJS Templates
lock: recognize parent locks while acquiring...
Siddharth Agarwal -
r26387:e16f80f8 default
parent child Browse files
Show More
@@ -102,7 +102,16 class lock(object):
102 self.held = 1
102 self.held = 1
103 except (OSError, IOError) as why:
103 except (OSError, IOError) as why:
104 if why.errno == errno.EEXIST:
104 if why.errno == errno.EEXIST:
105 locker = self.testlock()
105 locker = self._readlock()
106 # special case where a parent process holds the lock -- this
107 # is different from the pid being different because we do
108 # want the unlock and postrelease functions to be called,
109 # but the lockfile to not be removed.
110 if locker == self.parentlock:
111 self._parentheld = True
112 self.held = 1
113 return
114 locker = self._testlock(locker)
106 if locker is not None:
115 if locker is not None:
107 raise error.LockHeld(errno.EAGAIN,
116 raise error.LockHeld(errno.EAGAIN,
108 self.vfs.join(self.f), self.desc,
117 self.vfs.join(self.f), self.desc,
@@ -151,5 +151,106 class testlock(unittest.TestCase):
151 state.assertpostreleasecalled(True)
151 state.assertpostreleasecalled(True)
152 state.assertlockexists(False)
152 state.assertlockexists(False)
153
153
154 def testinheritlock(self):
155 d = tempfile.mkdtemp(dir=os.getcwd())
156 parentstate = teststate(self, d)
157 parentlock = parentstate.makelock()
158 parentstate.assertacquirecalled(True)
159
160 # set up lock inheritance
161 lockname = parentlock.prepinherit()
162 parentstate.assertreleasecalled(True)
163 parentstate.assertpostreleasecalled(False)
164 parentstate.assertlockexists(True)
165
166 childstate = teststate(self, d, pidoffset=1)
167 childlock = childstate.makelock(parentlock=lockname)
168 childstate.assertacquirecalled(True)
169
170 # release the child lock -- the lock file should still exist on disk
171 childlock.release()
172 childstate.assertreleasecalled(True)
173 childstate.assertpostreleasecalled(True)
174 childstate.assertlockexists(True)
175
176 parentstate.resetacquirefn()
177 parentlock.reacquire()
178 parentstate.assertacquirecalled(True)
179
180 parentlock.release()
181 parentstate.assertreleasecalled(True)
182 parentstate.assertpostreleasecalled(True)
183 parentstate.assertlockexists(False)
184
185 def testmultilock(self):
186 d = tempfile.mkdtemp(dir=os.getcwd())
187 state0 = teststate(self, d)
188 lock0 = state0.makelock()
189 state0.assertacquirecalled(True)
190
191 lock0name = lock0.prepinherit()
192 state0.assertreleasecalled(True)
193 state0.assertpostreleasecalled(False)
194 state0.assertlockexists(True)
195
196 state1 = teststate(self, d, pidoffset=1)
197 lock1 = state1.makelock(parentlock=lock0name)
198 state1.assertacquirecalled(True)
199
200 # from within lock1, acquire another lock
201 lock1name = lock1.prepinherit()
202 # since the file on disk is lock0's this should have the same name
203 self.assertEqual(lock0name, lock1name)
204
205 state2 = teststate(self, d, pidoffset=2)
206 lock2 = state2.makelock(parentlock=lock1name)
207 state2.assertacquirecalled(True)
208
209 lock2.release()
210 state2.assertreleasecalled(True)
211 state2.assertpostreleasecalled(True)
212 state2.assertlockexists(True)
213
214 state1.resetacquirefn()
215 lock1.reacquire()
216 state1.assertacquirecalled(True)
217
218 lock1.release()
219 state1.assertreleasecalled(True)
220 state1.assertpostreleasecalled(True)
221 state1.assertlockexists(True)
222
223 lock0.reacquire()
224 lock0.release()
225
226 def testinheritlockfork(self):
227 d = tempfile.mkdtemp(dir=os.getcwd())
228 parentstate = teststate(self, d)
229 parentlock = parentstate.makelock()
230 parentstate.assertacquirecalled(True)
231
232 # set up lock inheritance
233 lockname = parentlock.prepinherit()
234 childstate = teststate(self, d, pidoffset=1)
235 childlock = childstate.makelock(parentlock=lockname)
236 childstate.assertacquirecalled(True)
237
238 # fork the child lock
239 forkchildlock = copy.deepcopy(childlock)
240 forkchildlock._pidoffset += 1
241 forkchildlock.release()
242 childstate.assertreleasecalled(False)
243 childstate.assertpostreleasecalled(False)
244 childstate.assertlockexists(True)
245
246 # release the child lock
247 childlock.release()
248 childstate.assertreleasecalled(True)
249 childstate.assertpostreleasecalled(True)
250 childstate.assertlockexists(True)
251
252 parentlock.reacquire()
253 parentlock.release()
254
154 if __name__ == '__main__':
255 if __name__ == '__main__':
155 silenttestrunner.main(__name__)
256 silenttestrunner.main(__name__)
General Comments 0
You need to be logged in to leave comments. Login now