~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: 2010-09-01 08:02:42 UTC
  • mfrom: (5390.3.3 faster-revert-593560)
  • Revision ID: pqm@pqm.ubuntu.com-20100901080242-esg62ody4frwmy66
(spiv) Avoid repeatedly calling self.target.all_file_ids() in
 InterTree.iter_changes. (Andrew Bennetts)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006, 2007, 2008, 2009 Canonical Ltd
 
1
# Copyright (C) 2006-2010 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
151
151
# files/dirs created.
152
152
 
153
153
 
154
 
_DEFAULT_TIMEOUT_SECONDS = 300
 
154
_DEFAULT_TIMEOUT_SECONDS = 30
155
155
_DEFAULT_POLL_SECONDS = 1.0
156
156
 
157
157
 
243
243
        # have a similar bug allowing someone to think they got the lock
244
244
        # when it's already held.
245
245
        #
246
 
        # See <https://bugs.edge.launchpad.net/bzr/+bug/498378> for one case.
 
246
        # See <https://bugs.launchpad.net/bzr/+bug/498378> for one case.
247
247
        #
248
248
        # Strictly the check is unnecessary and a waste of time for most
249
249
        # people, but probably worth trapping if something is wrong.
252
252
        if info is None:
253
253
            raise LockFailed(self, "lock was renamed into place, but "
254
254
                "now is missing!")
255
 
        if info['nonce'] != self.nonce:
 
255
        if info.get('nonce') != self.nonce:
256
256
            self._trace("rename succeeded, "
257
257
                "but lock is still held by someone else")
258
258
            raise LockContention(self)
430
430
    def peek(self):
431
431
        """Check if the lock is held by anyone.
432
432
 
433
 
        If it is held, this returns the lock info structure as a rio Stanza,
 
433
        If it is held, this returns the lock info structure as a dict
434
434
        which contains some information about the current lock holder.
435
435
        Otherwise returns None.
436
436
        """
447
447
        # XXX: is creating this here inefficient?
448
448
        config = bzrlib.config.GlobalConfig()
449
449
        try:
450
 
            user = config.user_email()
451
 
        except errors.NoEmailInUsername:
452
450
            user = config.username()
 
451
        except errors.NoWhoami:
 
452
            user = osutils.getuser_unicode()
453
453
        s = rio.Stanza(hostname=get_host_name(),
454
454
                   pid=str(os.getpid()),
455
455
                   start_time=str(int(time.time())),
459
459
        return s.to_string()
460
460
 
461
461
    def _parse_info(self, info_bytes):
462
 
        # TODO: Handle if info_bytes is empty
463
 
        return rio.read_stanza(osutils.split_lines(info_bytes)).as_dict()
 
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()
464
470
 
465
471
    def attempt_lock(self):
466
472
        """Take the lock; fail if it's already held.
533
539
                if deadline_str is None:
534
540
                    deadline_str = time.strftime('%H:%M:%S',
535
541
                                                 time.localtime(deadline))
 
542
                # As local lock urls are correct we display them.
 
543
                # We avoid displaying remote lock urls.
536
544
                lock_url = self.transport.abspath(self.path)
537
 
                # See <https://bugs.edge.launchpad.net/bzr/+bug/250451>
538
 
                # the URL here is sometimes not one that is useful to the
539
 
                # user, perhaps being wrapped in a lp-%d or chroot decorator,
540
 
                # especially if this error is issued from the server.
541
 
                self._report_function('%s %s\n'
542
 
                    '%s\n' # held by
543
 
                    '%s\n' # locked ... ago
544
 
                    'Will continue to try until %s, unless '
545
 
                    'you press Ctrl-C.\n'
546
 
                    'See "bzr help break-lock" for more.',
547
 
                    start,
548
 
                    formatted_info[0],
549
 
                    formatted_info[1],
550
 
                    formatted_info[2],
551
 
                    deadline_str,
552
 
                    )
553
 
 
 
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)
554
563
            if (max_attempts is not None) and (attempt_count >= max_attempts):
555
564
                self._trace("exceeded %d attempts")
556
565
                raise LockContention(self)
558
567
                self._trace("waiting %ss", poll)
559
568
                time.sleep(poll)
560
569
            else:
 
570
                # As timeout is always 0 for remote locks
 
571
                # this block is applicable only for local
 
572
                # lock contention
561
573
                self._trace("timeout after waiting %ss", timeout)
562
 
                raise LockContention(self)
 
574
                raise LockContention('(local)', lock_url)
563
575
 
564
576
    def leave_in_place(self):
565
577
        self._locked_via_token = True
610
622
 
611
623
    def _format_lock_info(self, info):
612
624
        """Turn the contents of peek() into something for the user"""
613
 
        lock_url = self.transport.abspath(self.path)
614
 
        delta = time.time() - int(info['start_time'])
 
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>')
615
633
        return [
616
 
            'lock %s' % (lock_url,),
617
 
            'held by %(user)s on host %(hostname)s [process #%(pid)s]' % info,
618
 
            'locked %s' % (format_delta(delta),),
 
634
            user,
 
635
            hostname,
 
636
            pid,
 
637
            time_ago,
619
638
            ]
620
639
 
621
640
    def validate_token(self, token):