~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/config.py

More doc and ensure that the config is locked when _write_config_file is called.

Show diffs side-by-side

added added

removed removed

Lines of Context:
535
535
 
536
536
    If several processes try to write the config file, the accesses need to be
537
537
    serialized.
 
538
 
 
539
    Daughter classes should decorate all methods that update a config with the
 
540
    ``@needs_write_lock`` decorator (they call, directly or indirectly, the
 
541
    ``_write_config_file()`` method. These methods (typically ``set_option()``
 
542
    and variants must reload the config file from disk before calling
 
543
    ``_write_config_file()``), this can be achieved by calling the
 
544
    ``self.reload()`` method. Note that the lock scope should cover both the
 
545
    reading and the writing of the config file which is why the decorator can't
 
546
    be applied to ``_write_config_file()`` only.
 
547
 
 
548
    This should be enough to implement the following logic:
 
549
    - lock for exclusive write access,
 
550
    - reload the config file from disk,
 
551
    - set the new value
 
552
    - unlock
 
553
 
 
554
    This logic guarantees that a writer can update a value without erasing an
 
555
    update made by another writer.
538
556
    """
539
557
 
540
558
    lock_name = 'lock'
547
565
        self._lock = lockdir.LockDir(self.transport, 'lock')
548
566
 
549
567
    def lock_write(self, token=None):
 
568
        """Takes a write lock in the directory containing the config file.
 
569
 
 
570
        If the directory doesn't exist it is created.
 
571
        """
550
572
        ensure_config_dir_exists(self.dir)
551
573
        return self._lock.lock_write(token)
552
574
 
553
575
    def unlock(self):
554
576
        self._lock.unlock()
555
577
 
 
578
    def _write_config_file(self):
 
579
        if self._lock is None or not self._lock.is_held:
 
580
            # NB: if the following exception is raised it probably means a
 
581
            # missing @needs_write_lock decorator on one of the callers.
 
582
            raise errors.ObjectNotLocked(self)
 
583
        super(LockableConfig, self)._write_config_file()
 
584
 
556
585
 
557
586
class GlobalConfig(LockableConfig):
558
587
    """The configuration that should be used for a specific location."""
576
605
        else:
577
606
            return {}
578
607
 
 
608
    @needs_write_lock
579
609
    def set_alias(self, alias_name, alias_command):
580
610
        """Save the alias in the configuration."""
581
611
        self._set_option(alias_name, alias_command, 'ALIASES')
582
612
 
 
613
    @needs_write_lock
583
614
    def unset_alias(self, alias_name):
584
615
        """Unset an existing alias."""
585
616
        aliases = self._get_parser().get('ALIASES')