Show More
@@ -102,7 +102,16 class lock(object): | |||
|
102 | 102 | self.held = 1 |
|
103 | 103 | except (OSError, IOError) as why: |
|
104 | 104 | if why.errno == errno.EEXIST: |
|
105 |
locker = self. |
|
|
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 | 115 | if locker is not None: |
|
107 | 116 | raise error.LockHeld(errno.EAGAIN, |
|
108 | 117 | self.vfs.join(self.f), self.desc, |
@@ -151,5 +151,106 class testlock(unittest.TestCase): | |||
|
151 | 151 | state.assertpostreleasecalled(True) |
|
152 | 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 | 255 | if __name__ == '__main__': |
|
155 | 256 | silenttestrunner.main(__name__) |
General Comments 0
You need to be logged in to leave comments.
Login now