~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/cethread.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2011-02-16 19:22:55 UTC
  • mfrom: (5664.1.1 document-no-tree)
  • Revision ID: pqm@pqm.ubuntu.com-20110216192255-ihgckago297tcp5z
(jelmer) Document no_tree argument to ControlDir.clone_on_transport. (Jelmer
 Vernooij)

Show diffs side-by-side

added added

removed removed

Lines of Context:
39
39
        self.set_sync_event(sync_event)
40
40
        self.exception = None
41
41
        self.ignored_exceptions = None # see set_ignored_exceptions
 
42
        self.lock = threading.Lock()
42
43
 
43
44
    # compatibility thunk for python-2.4 and python-2.5...
44
45
    if sys.version_info < (2, 6):
55
56
        Some threads require multiple events and should set the relevant one
56
57
        when appropriate.
57
58
 
58
 
        Note that the event should be cleared so the caller can wait() on him
59
 
        and be released when the thread set the event.
 
59
        Note that the event should be initially cleared so the caller can
 
60
        wait() on him and be released when the thread set the event.
 
61
 
 
62
        Also note that the thread can use multiple events, setting them as it
 
63
        progress, while the caller can chose to wait on any of them. What
 
64
        matters is that there is always one event set so that the caller is
 
65
        always released when an exception is caught. Re-using the same event is
 
66
        therefore risky as the thread itself has no idea about which event the
 
67
        caller is waiting on. If the caller has already been released then a
 
68
        cleared event won't guarantee that the caller is still waiting on it.
60
69
        """
61
70
        self.sync_event = event
62
71
 
 
72
    def switch_and_set(self, new):
 
73
        """Switch to a new ``sync_event`` and set the current one.
 
74
 
 
75
        Using this method protects against race conditions while setting a new
 
76
        ``sync_event``.
 
77
 
 
78
        Note that this allows a caller to wait either on the old or the new
 
79
        event depending on whether it wants a fine control on what is happening
 
80
        inside a thread.
 
81
 
 
82
        :param new: The event that will become ``sync_event``
 
83
        """
 
84
        cur = self.sync_event
 
85
        self.lock.acquire()
 
86
        try: # Always release the lock
 
87
            try:
 
88
                self.set_sync_event(new)
 
89
                # From now on, any exception will be synced with the new event
 
90
            except:
 
91
                # Unlucky, we couldn't set the new sync event, try restoring a
 
92
                # safe state
 
93
                self.set_sync_event(cur)
 
94
                raise
 
95
            # Setting the current ``sync_event`` will release callers waiting
 
96
            # on it, note that it will also be set in run() if an exception is
 
97
            # raised
 
98
            cur.set()
 
99
        finally:
 
100
            self.lock.release()
 
101
 
63
102
    def set_ignored_exceptions(self, ignored):
64
103
        """Declare which exceptions will be ignored.
65
104