~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/lockdir.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2009-08-13 14:20:03 UTC
  • mfrom: (4599.2.4 windows-installer)
  • Revision ID: pqm@pqm.ubuntu.com-20090813142003-3x748ymw3avzmme7
(jam) Updates to the windows installers.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006-2010 Canonical Ltd
 
1
# Copyright (C) 2006, 2007, 2008 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
110
110
    debug,
111
111
    errors,
112
112
    lock,
113
 
    osutils,
114
113
    )
115
114
import bzrlib.config
116
 
from bzrlib.decorators import only_raises
117
115
from bzrlib.errors import (
118
116
        DirectoryNotEmpty,
119
117
        FileExists,
151
149
# files/dirs created.
152
150
 
153
151
 
154
 
_DEFAULT_TIMEOUT_SECONDS = 30
 
152
_DEFAULT_TIMEOUT_SECONDS = 300
155
153
_DEFAULT_POLL_SECONDS = 1.0
156
154
 
157
155
 
242
240
        # incorrect.  It's possible some other servers or filesystems will
243
241
        # have a similar bug allowing someone to think they got the lock
244
242
        # when it's already held.
245
 
        #
246
 
        # See <https://bugs.launchpad.net/bzr/+bug/498378> for one case.
247
 
        #
248
 
        # Strictly the check is unnecessary and a waste of time for most
249
 
        # people, but probably worth trapping if something is wrong.
250
243
        info = self.peek()
251
244
        self._trace("after locking, info=%r", info)
252
 
        if info is None:
253
 
            raise LockFailed(self, "lock was renamed into place, but "
254
 
                "now is missing!")
255
 
        if info.get('nonce') != self.nonce:
 
245
        if info['nonce'] != self.nonce:
256
246
            self._trace("rename succeeded, "
257
247
                "but lock is still held by someone else")
258
248
            raise LockContention(self)
296
286
                                            info_bytes)
297
287
        return tmpname
298
288
 
299
 
    @only_raises(LockNotHeld, LockBroken)
300
289
    def unlock(self):
301
290
        """Release a held lock
302
291
        """
425
414
 
426
415
        peek() reads the info file of the lock holder, if any.
427
416
        """
428
 
        return self._parse_info(self.transport.get_bytes(path))
 
417
        return self._parse_info(self.transport.get(path))
429
418
 
430
419
    def peek(self):
431
420
        """Check if the lock is held by anyone.
432
421
 
433
 
        If it is held, this returns the lock info structure as a dict
 
422
        If it is held, this returns the lock info structure as a rio Stanza,
434
423
        which contains some information about the current lock holder.
435
424
        Otherwise returns None.
436
425
        """
447
436
        # XXX: is creating this here inefficient?
448
437
        config = bzrlib.config.GlobalConfig()
449
438
        try:
 
439
            user = config.user_email()
 
440
        except errors.NoEmailInUsername:
450
441
            user = config.username()
451
 
        except errors.NoWhoami:
452
 
            user = osutils.getuser_unicode()
453
442
        s = rio.Stanza(hostname=get_host_name(),
454
443
                   pid=str(os.getpid()),
455
444
                   start_time=str(int(time.time())),
458
447
                   )
459
448
        return s.to_string()
460
449
 
461
 
    def _parse_info(self, info_bytes):
462
 
        stanza = rio.read_stanza(osutils.split_lines(info_bytes))
463
 
        if stanza is None:
464
 
            # see bug 185013; we fairly often end up with the info file being
465
 
            # empty after an interruption; we could log a message here but
466
 
            # there may not be much we can say
467
 
            return {}
468
 
        else:
469
 
            return stanza.as_dict()
 
450
    def _parse_info(self, info_file):
 
451
        return rio.read_stanza(info_file.readlines()).as_dict()
470
452
 
471
453
    def attempt_lock(self):
472
454
        """Take the lock; fail if it's already held.
539
521
                if deadline_str is None:
540
522
                    deadline_str = time.strftime('%H:%M:%S',
541
523
                                                 time.localtime(deadline))
542
 
                # As local lock urls are correct we display them.
543
 
                # We avoid displaying remote lock urls.
544
524
                lock_url = self.transport.abspath(self.path)
545
 
                if lock_url.startswith('file://'):
546
 
                    lock_url = lock_url.split('.bzr/')[0]
547
 
                else:
548
 
                    lock_url = ''
549
 
                user, hostname, pid, time_ago = formatted_info
550
 
                msg = ('%s lock %s '        # lock_url
551
 
                    'held by '              # start
552
 
                    '%s\n'                  # user
553
 
                    'at %s '                # hostname
554
 
                    '[process #%s], '       # pid
555
 
                    'acquired %s.')         # time ago
556
 
                msg_args = [start, lock_url, user, hostname, pid, time_ago]
557
 
                if timeout > 0:
558
 
                    msg += ('\nWill continue to try until %s, unless '
559
 
                        'you press Ctrl-C.')
560
 
                    msg_args.append(deadline_str)
561
 
                msg += '\nSee "bzr help break-lock" for more.'
562
 
                self._report_function(msg, *msg_args)
 
525
                self._report_function('%s %s\n'
 
526
                                      '%s\n' # held by
 
527
                                      '%s\n' # locked ... ago
 
528
                                      'Will continue to try until %s, unless '
 
529
                                      'you press Ctrl-C\n'
 
530
                                      'If you\'re sure that it\'s not being '
 
531
                                      'modified, use bzr break-lock %s',
 
532
                                      start,
 
533
                                      formatted_info[0],
 
534
                                      formatted_info[1],
 
535
                                      formatted_info[2],
 
536
                                      deadline_str,
 
537
                                      lock_url)
 
538
 
563
539
            if (max_attempts is not None) and (attempt_count >= max_attempts):
564
540
                self._trace("exceeded %d attempts")
565
541
                raise LockContention(self)
567
543
                self._trace("waiting %ss", poll)
568
544
                time.sleep(poll)
569
545
            else:
570
 
                # As timeout is always 0 for remote locks
571
 
                # this block is applicable only for local
572
 
                # lock contention
573
546
                self._trace("timeout after waiting %ss", timeout)
574
 
                raise LockContention('(local)', lock_url)
 
547
                raise LockContention(self)
575
548
 
576
549
    def leave_in_place(self):
577
550
        self._locked_via_token = True
622
595
 
623
596
    def _format_lock_info(self, info):
624
597
        """Turn the contents of peek() into something for the user"""
625
 
        start_time = info.get('start_time')
626
 
        if start_time is None:
627
 
            time_ago = '(unknown)'
628
 
        else:
629
 
            time_ago = format_delta(time.time() - int(info['start_time']))
630
 
        user = info.get('user', '<unknown>')
631
 
        hostname = info.get('hostname', '<unknown>')
632
 
        pid = info.get('pid', '<unknown>')
 
598
        lock_url = self.transport.abspath(self.path)
 
599
        delta = time.time() - int(info['start_time'])
633
600
        return [
634
 
            user,
635
 
            hostname,
636
 
            pid,
637
 
            time_ago,
 
601
            'lock %s' % (lock_url,),
 
602
            'held by %(user)s on host %(hostname)s [process #%(pid)s]' % info,
 
603
            'locked %s' % (format_delta(delta),),
638
604
            ]
639
605
 
640
606
    def validate_token(self, token):