~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/lockdir.py

  • Committer: Matt Nordhoff
  • Date: 2009-10-22 08:28:04 UTC
  • mto: (4797.2.18 2.1)
  • mto: This revision was merged to the branch mainline in revision 5045.
  • Revision ID: mnordhoff@mattnordhoff.com-20091022082804-outyhrw2y14fxt4x
Make StaticTuple_New always raise a ValueError, and StaticTuple_new_constructor always raise a TypeError.

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
115
from bzrlib.decorators import only_raises
151
150
# files/dirs created.
152
151
 
153
152
 
154
 
_DEFAULT_TIMEOUT_SECONDS = 30
 
153
_DEFAULT_TIMEOUT_SECONDS = 300
155
154
_DEFAULT_POLL_SECONDS = 1.0
156
155
 
157
156
 
242
241
        # incorrect.  It's possible some other servers or filesystems will
243
242
        # have a similar bug allowing someone to think they got the lock
244
243
        # 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
244
        info = self.peek()
251
245
        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:
 
246
        if info['nonce'] != self.nonce:
256
247
            self._trace("rename succeeded, "
257
248
                "but lock is still held by someone else")
258
249
            raise LockContention(self)
425
416
 
426
417
        peek() reads the info file of the lock holder, if any.
427
418
        """
428
 
        return self._parse_info(self.transport.get_bytes(path))
 
419
        return self._parse_info(self.transport.get(path))
429
420
 
430
421
    def peek(self):
431
422
        """Check if the lock is held by anyone.
432
423
 
433
 
        If it is held, this returns the lock info structure as a dict
 
424
        If it is held, this returns the lock info structure as a rio Stanza,
434
425
        which contains some information about the current lock holder.
435
426
        Otherwise returns None.
436
427
        """
447
438
        # XXX: is creating this here inefficient?
448
439
        config = bzrlib.config.GlobalConfig()
449
440
        try:
 
441
            user = config.user_email()
 
442
        except errors.NoEmailInUsername:
450
443
            user = config.username()
451
 
        except errors.NoWhoami:
452
 
            user = osutils.getuser_unicode()
453
444
        s = rio.Stanza(hostname=get_host_name(),
454
445
                   pid=str(os.getpid()),
455
446
                   start_time=str(int(time.time())),
458
449
                   )
459
450
        return s.to_string()
460
451
 
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()
 
452
    def _parse_info(self, info_file):
 
453
        return rio.read_stanza(info_file.readlines()).as_dict()
470
454
 
471
455
    def attempt_lock(self):
472
456
        """Take the lock; fail if it's already held.
539
523
                if deadline_str is None:
540
524
                    deadline_str = time.strftime('%H:%M:%S',
541
525
                                                 time.localtime(deadline))
542
 
                # As local lock urls are correct we display them.
543
 
                # We avoid displaying remote lock urls.
544
526
                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)
 
527
                self._report_function('%s %s\n'
 
528
                                      '%s\n' # held by
 
529
                                      '%s\n' # locked ... ago
 
530
                                      'Will continue to try until %s, unless '
 
531
                                      'you press Ctrl-C\n'
 
532
                                      'If you\'re sure that it\'s not being '
 
533
                                      'modified, use bzr break-lock %s',
 
534
                                      start,
 
535
                                      formatted_info[0],
 
536
                                      formatted_info[1],
 
537
                                      formatted_info[2],
 
538
                                      deadline_str,
 
539
                                      lock_url)
 
540
 
563
541
            if (max_attempts is not None) and (attempt_count >= max_attempts):
564
542
                self._trace("exceeded %d attempts")
565
543
                raise LockContention(self)
567
545
                self._trace("waiting %ss", poll)
568
546
                time.sleep(poll)
569
547
            else:
570
 
                # As timeout is always 0 for remote locks
571
 
                # this block is applicable only for local
572
 
                # lock contention
573
548
                self._trace("timeout after waiting %ss", timeout)
574
 
                raise LockContention('(local)', lock_url)
 
549
                raise LockContention(self)
575
550
 
576
551
    def leave_in_place(self):
577
552
        self._locked_via_token = True
622
597
 
623
598
    def _format_lock_info(self, info):
624
599
        """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>')
 
600
        lock_url = self.transport.abspath(self.path)
 
601
        delta = time.time() - int(info['start_time'])
633
602
        return [
634
 
            user,
635
 
            hostname,
636
 
            pid,
637
 
            time_ago,
 
603
            'lock %s' % (lock_url,),
 
604
            'held by %(user)s on host %(hostname)s [process #%(pid)s]' % info,
 
605
            'locked %s' % (format_delta(delta),),
638
606
            ]
639
607
 
640
608
    def validate_token(self, token):