~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/remote.py

Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
smart protocol as appropriate, so that locking operations on RemoteRepositories
work correctly.

Show diffs side-by-side

added added

removed removed

Lines of Context:
192
192
        self._lock_mode = None
193
193
        self._lock_token = None
194
194
        self._lock_count = 0
 
195
        self._leave_lock = False
195
196
 
196
197
    def _ensure_real(self):
197
198
        """Ensure that there is a _real_repository set.
279
280
        if not self._lock_mode:
280
281
            self._lock_mode = 'r'
281
282
            self._lock_count = 1
 
283
            if self._real_repository is not None:
 
284
                self._real_repository.lock_read()
282
285
        else:
283
286
            self._lock_count += 1
284
 
        self._ensure_real()
285
 
        return self._real_repository.lock_read()
 
287
 
 
288
    def _lock_write(self, token):
 
289
        path = self.bzrdir._path_for_remote_call(self._client)
 
290
        if token is None:
 
291
            token = ''
 
292
        response = self._client.call('Repository.lock_write', path, token)
 
293
        if response[0] == 'ok':
 
294
            ok, token = response
 
295
            return token
 
296
        elif response[0] == 'LockContention':
 
297
            raise errors.LockContention('(remote lock)')
 
298
        else:
 
299
            assert False, 'unexpected response code %s' % (response,)
286
300
 
287
301
    def lock_write(self, token=None):
288
 
        # definately wrong: want to check if there is a real repo
289
 
        # and not thunk through if not
290
302
        if not self._lock_mode:
291
 
            self._ensure_real()
292
 
            self._lock_token = self._real_repository.lock_write(token=token)
 
303
            self._lock_token = self._lock_write(token)
 
304
            assert self._lock_token, 'Remote server did not return a token!'
 
305
            if self._real_repository is not None:
 
306
                self._real_repository.lock_write(token=self._lock_token)
 
307
            if token is not None:
 
308
                self._leave_lock = True
 
309
            else:
 
310
                self._leave_lock = False
293
311
            self._lock_mode = 'w'
294
312
            self._lock_count = 1
295
313
        elif self._lock_mode == 'r':
299
317
        return self._lock_token
300
318
 
301
319
    def leave_lock_in_place(self):
302
 
        self._real_repository.leave_lock_in_place()
 
320
        self._leave_lock = True
303
321
 
304
322
    def dont_leave_lock_in_place(self):
305
 
        self._real_repository.dont_leave_lock_in_place()
 
323
        self._leave_lock = False
306
324
 
307
325
    def _set_real_repository(self, repository):
308
326
        """Set the _real_repository for this repository.
316
334
            # acquire the lock with our token.
317
335
            self._real_repository.lock_write(self._lock_token)
318
336
 
 
337
    def _unlock(self, token):
 
338
        path = self.bzrdir._path_for_remote_call(self._client)
 
339
        response = self._client.call('Repository.unlock', path, token)
 
340
        if response == ('ok',):
 
341
            return
 
342
        elif response[0] == 'TokenMismatch':
 
343
            raise errors.TokenMismatch(token, '(remote token)')
 
344
        else:
 
345
            assert False, 'unexpected response code %s' % (response,)
 
346
 
319
347
    def unlock(self):
320
 
        # should free cache context.
321
348
        self._lock_count -= 1
322
349
        if not self._lock_count:
 
350
            mode = self._lock_mode
323
351
            self._lock_mode = None
 
352
            if self._real_repository is not None:
 
353
                self._real_repository.unlock()
 
354
            if mode != 'w':
 
355
                return
 
356
            assert self._lock_token, 'Locked, but no token!'
 
357
            token = self._lock_token
324
358
            self._lock_token = None
325
 
            return self._real_repository.unlock()
 
359
            if not self._leave_lock:
 
360
                self._unlock(token)
326
361
 
327
362
    def break_lock(self):
328
 
        # should hand off to the network - or better yet, we should not
329
 
        # allow stale network locks ?
 
363
        # should hand off to the network
330
364
        self._ensure_real()
331
365
        return self._real_repository.break_lock()
332
366