~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/inter.py

merge bzr.dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
29
29
    operations with another of similar type - they will always forward to
30
30
    a subclass of InterObject - i.e. 
31
31
    InterVersionedFile.get(other).method_name(parameters).
 
32
 
 
33
    If the source and target objects implement the locking protocol - 
 
34
    lock_read, lock_write, unlock, then the InterObject's lock_read,
 
35
    lock_write and unlock methods may be used (optionally in conjunction with
 
36
    the needs_read_lock and needs_write_lock decorators.)
32
37
    """
33
38
 
34
39
    # _optimisers = set()
47
52
        self.source = source
48
53
        self.target = target
49
54
 
 
55
    def _double_lock(self, lock_source, lock_target):
 
56
        """Take out two locks, rolling back the first if the second throws."""
 
57
        lock_source()
 
58
        try:
 
59
            lock_target()
 
60
        except Exception:
 
61
            # we want to ensure that we don't leave source locked by mistake.
 
62
            # and any error on target should not confuse source.
 
63
            self.source.unlock()
 
64
            raise
 
65
 
50
66
    @classmethod
51
67
    def get(klass, source, target):
52
68
        """Retrieve a Inter worker object for these objects.
63
79
                return provider(source, target)
64
80
        return klass(source, target)
65
81
 
 
82
    def lock_read(self):
 
83
        """Take out a logical read lock.
 
84
 
 
85
        This will lock the source branch and the target branch. The source gets
 
86
        a read lock and the target a read lock.
 
87
        """
 
88
        self._double_lock(self.source.lock_read, self.target.lock_read)
 
89
 
 
90
    def lock_write(self):
 
91
        """Take out a logical write lock.
 
92
 
 
93
        This will lock the source branch and the target branch. The source gets
 
94
        a read lock and the target a write lock.
 
95
        """
 
96
        self._double_lock(self.source.lock_read, self.target.lock_write)
 
97
 
66
98
    @classmethod
67
99
    def register_optimiser(klass, optimiser):
68
100
        """Register an InterObject optimiser."""
69
101
        klass._optimisers.add(optimiser)
70
102
 
 
103
    def unlock(self):
 
104
        """Release the locks on source and target."""
 
105
        try:
 
106
            self.target.unlock()
 
107
        finally:
 
108
            self.source.unlock()
 
109
 
71
110
    @classmethod
72
111
    def unregister_optimiser(klass, optimiser):
73
112
        """Unregister an InterObject optimiser."""