~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/lockdir.py

  • Committer: Robert Collins
  • Date: 2007-04-23 02:29:35 UTC
  • mfrom: (2441 +trunk)
  • mto: This revision was merged to the branch mainline in revision 2442.
  • Revision ID: robertc@robertcollins.net-20070423022935-9hhongamvk6bfdso
Resolve conflicts with bzr.dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
160
160
        self.transport = transport
161
161
        self.path = path
162
162
        self._lock_held = False
 
163
        self._locked_via_token = False
163
164
        self._fake_read_lock = False
164
165
        self._held_dir = path + '/held'
165
166
        self._held_info_path = self._held_dir + self.__INFO_NAME
166
167
        self._file_modebits = file_modebits
167
168
        self._dir_modebits = dir_modebits
168
 
        self.nonce = rand_chars(20)
169
169
 
170
170
        self._report_function = note
171
171
 
209
209
                # After creating the lock directory, try again
210
210
                self.transport.mkdir(tmpname)
211
211
 
 
212
            self.nonce = rand_chars(20)
212
213
            info_bytes = self._prepare_info()
213
214
            # We use put_file_non_atomic because we just created a new unique
214
215
            # directory so we don't have to worry about files existing there.
234
235
            return
235
236
        if not self._lock_held:
236
237
            raise LockNotHeld(self)
237
 
        # rename before deleting, because we can't atomically remove the whole
238
 
        # tree
239
 
        tmpname = '%s/releasing.%s.tmp' % (self.path, rand_chars(20))
240
 
        # gotta own it to unlock
241
 
        self.confirm()
242
 
        self.transport.rename(self._held_dir, tmpname)
243
 
        self._lock_held = False
244
 
        self.transport.delete(tmpname + self.__INFO_NAME)
245
 
        self.transport.rmdir(tmpname)
 
238
        if self._locked_via_token:
 
239
            self._locked_via_token = False
 
240
            self._lock_held = False
 
241
        else:
 
242
            # rename before deleting, because we can't atomically remove the
 
243
            # whole tree
 
244
            tmpname = '%s/releasing.%s.tmp' % (self.path, rand_chars(20))
 
245
            # gotta own it to unlock
 
246
            self.confirm()
 
247
            self.transport.rename(self._held_dir, tmpname)
 
248
            self._lock_held = False
 
249
            self.transport.delete(tmpname + self.__INFO_NAME)
 
250
            self.transport.rmdir(tmpname)
246
251
 
247
252
    def break_lock(self):
248
253
        """Break a lock not held by this instance of LockDir.
414
419
                time.sleep(poll)
415
420
            else:
416
421
                raise LockContention(self)
417
 
 
418
 
    def lock_write(self):
419
 
        """Wait for and acquire the lock."""
420
 
        self.wait_lock()
 
422
    
 
423
    def leave_in_place(self):
 
424
        self._locked_via_token = True
 
425
 
 
426
    def dont_leave_in_place(self):
 
427
        self._locked_via_token = False
 
428
 
 
429
    def lock_write(self, token=None):
 
430
        """Wait for and acquire the lock.
 
431
        
 
432
        :param token: if this is already locked, then lock_write will fail
 
433
            unless the token matches the existing lock.
 
434
        :returns: a token if this instance supports tokens, otherwise None.
 
435
        :raises TokenLockingNotSupported: when a token is given but this
 
436
            instance doesn't support using token locks.
 
437
        :raises MismatchedToken: if the specified token doesn't match the token
 
438
            of the existing lock.
 
439
 
 
440
        A token should be passed in if you know that you have locked the object
 
441
        some other way, and need to synchronise this object's state with that
 
442
        fact.
 
443
         
 
444
        XXX: docstring duplicated from LockableFiles.lock_write.
 
445
        """
 
446
        if token is not None:
 
447
            self.validate_token(token)
 
448
            self.nonce = token
 
449
            self._lock_held = True
 
450
            self._locked_via_token = True
 
451
            return token
 
452
        else:
 
453
            self.wait_lock()
 
454
            return self.peek().get('nonce')
421
455
 
422
456
    def lock_read(self):
423
457
        """Compatibility-mode shared lock.
457
491
            'locked %s' % (format_delta(delta),),
458
492
            ]
459
493
 
 
494
    def validate_token(self, token):
 
495
        if token is not None:
 
496
            info = self.peek()
 
497
            if info is None:
 
498
                # Lock isn't held
 
499
                lock_token = None
 
500
            else:
 
501
                lock_token = info.get('nonce')
 
502
            if token != lock_token:
 
503
                raise errors.TokenMismatch(token, lock_token)
 
504