~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/inter.py

  • Committer: John Arbash Meinel
  • Date: 2006-10-06 07:25:55 UTC
  • mto: This revision was merged to the branch mainline in revision 2071.
  • Revision ID: john@arbash-meinel.com-20061006072555-b41c9a6f481fd1d6
Make bzrlib.config use lazy importing

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
 
    # _optimisers = set()
35
 
    # Each concrete InterObject type should have its own optimisers set.
 
39
    # _optimisers = list()
 
40
    # Each concrete InterObject type should have its own optimisers list.
36
41
 
37
42
    def __init__(self, source, target):
38
43
        """Construct a default InterObject instance. Please use 'get'.
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.
58
74
        If an optimised worker exists it will be used otherwise
59
75
        a default Inter worker instance will be created.
60
76
        """
61
 
        for provider in klass._optimisers:
 
77
        for provider in reversed(klass._optimisers):
62
78
            if provider.is_compatible(source, target):
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
 
        klass._optimisers.add(optimiser)
 
101
        klass._optimisers.append(optimiser)
 
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()
70
109
 
71
110
    @classmethod
72
111
    def unregister_optimiser(klass, optimiser):