~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/branch.py

  • Committer: Robert Collins
  • Date: 2009-04-15 04:45:06 UTC
  • mto: This revision was merged to the branch mainline in revision 4292.
  • Revision ID: robertc@robertcollins.net-20090415044506-30fnvsa3ukai60xb
Fix up lock correctness to deal with adding fallback repositories to locked branch objects.

Show diffs side-by-side

added added

removed removed

Lines of Context:
99
99
    def _open_hook(self):
100
100
        """Called by init to allow simpler extension of the base class."""
101
101
 
102
 
    def _activate_fallback_location(self, url):
 
102
    def _activate_fallback_location(self, url, lock_style):
103
103
        """Activate the branch/repository from url as a fallback repository."""
104
 
        self.repository.add_fallback_repository(
105
 
            self._get_fallback_repository(url))
 
104
        repo = self._get_fallback_repository(url)
 
105
        if lock_style == 'write':
 
106
            repo.lock_write()
 
107
        elif lock_style == 'read':
 
108
            repo.lock_read()
 
109
        self.repository.add_fallback_repository(repo)
106
110
 
107
111
    def break_lock(self):
108
112
        """Break a lock if one is present from another instance.
608
612
            url = urlutils.relative_url(self.base, url)
609
613
        self._set_parent_location(url)
610
614
 
 
615
    @needs_write_lock
611
616
    def set_stacked_on_url(self, url):
612
617
        """Set the URL this branch is stacked against.
613
618
 
626
631
                errors.UnstackableRepositoryFormat):
627
632
                return
628
633
            url = ''
 
634
            # XXX: Lock correctness - should unlock our old repo if we were
 
635
            # locked.
629
636
            # repositories don't offer an interface to remove fallback
630
637
            # repositories today; take the conceptually simpler option and just
631
638
            # reopen it.
632
639
            self.repository = self.bzrdir.find_repository()
 
640
            self.repository.lock_write()
633
641
            # for every revision reference the branch has, ensure it is pulled
634
642
            # in.
635
643
            source_repository = self._get_fallback_repository(old_url)
638
646
                self.repository.fetch(source_repository, revision_id,
639
647
                    find_ghosts=True)
640
648
        else:
641
 
            self._activate_fallback_location(url)
 
649
            self._activate_fallback_location(url, 'write')
642
650
        # write this out after the repository is stacked to avoid setting a
643
651
        # stacked config that doesn't work.
644
652
        self._set_config_location('stacked_on_location', url)
1016
1024
                     be truncated to end with revision_id.
1017
1025
        """
1018
1026
        result = to_bzrdir.create_branch()
 
1027
        result.lock_write()
1019
1028
        try:
1020
1029
            if repository_policy is not None:
1021
1030
                repository_policy.configure_branch(result)
1921
1930
        return self.control_files.is_locked()
1922
1931
 
1923
1932
    def lock_write(self, token=None):
1924
 
        repo_token = self.repository.lock_write()
 
1933
        repo_control = getattr(self.repository, 'control_files', None)
 
1934
        if self.control_files is repo_control or not self.is_locked():
 
1935
            self.repository.lock_write()
 
1936
            took_lock = True
 
1937
        else:
 
1938
            took_lock = False
1925
1939
        try:
1926
 
            token = self.control_files.lock_write(token=token)
 
1940
            return self.control_files.lock_write(token=token)
1927
1941
        except:
1928
 
            self.repository.unlock()
 
1942
            if took_lock:
 
1943
                self.repository.unlock()
1929
1944
            raise
1930
 
        return token
1931
1945
 
1932
1946
    def lock_read(self):
1933
 
        self.repository.lock_read()
 
1947
        repo_control = getattr(self.repository, 'control_files', None)
 
1948
        if self.control_files is repo_control or not self.is_locked():
 
1949
            self.repository.lock_read()
 
1950
            took_lock = True
 
1951
        else:
 
1952
            took_lock = False
1934
1953
        try:
1935
1954
            self.control_files.lock_read()
1936
1955
        except:
1937
 
            self.repository.unlock()
 
1956
            if took_lock:
 
1957
                self.repository.unlock()
1938
1958
            raise
1939
1959
 
1940
1960
    def unlock(self):
1941
 
        # TODO: test for failed two phase locks. This is known broken.
1942
 
        try:
1943
 
            self.control_files.unlock()
1944
 
        finally:
 
1961
        self.control_files.unlock()
 
1962
        repo_control = getattr(self.repository, 'control_files', None)
 
1963
        if (self.control_files is repo_control or
 
1964
            not self.control_files.is_locked()):
1945
1965
            self.repository.unlock()
1946
1966
        if not self.control_files.is_locked():
1947
1967
            # we just released the lock
2370
2390
                    raise AssertionError(
2371
2391
                        "'transform_fallback_location' hook %s returned "
2372
2392
                        "None, not a URL." % hook_name)
2373
 
            self._activate_fallback_location(url)
 
2393
            self._activate_fallback_location(url, None)
2374
2394
 
2375
2395
    def __init__(self, *args, **kwargs):
2376
2396
        self._ignore_fallbacks = kwargs.get('ignore_fallbacks', False)