~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/thread.py

  • Committer: Vincent Ladeuil
  • Date: 2011-02-08 16:26:23 UTC
  • mto: This revision was merged to the branch mainline in revision 5655.
  • Revision ID: v.ladeuil+lp@free.fr-20110208162623-2njflo8y7rrtek3n
Use clearer names.

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
import threading
19
19
 
20
20
 
21
 
class ThreadWithException(threading.Thread):
22
 
    """A catching exception thread.
 
21
class CatchingExceptionThread(threading.Thread):
 
22
    """A thread that keeps track of exceptions.
23
23
 
24
24
    If an exception occurs during the thread execution, it's caught and
25
25
    re-raised when the thread is joined().
31
31
        # blocked. The main example is a calling thread that want to wait for
32
32
        # the called thread to be in a given state before continuing.
33
33
        try:
34
 
            event = kwargs.pop('event')
 
34
            sync_event = kwargs.pop('sync_event')
35
35
        except KeyError:
36
36
            # If the caller didn't pass a specific event, create our own
37
 
            event = threading.Event()
38
 
        super(ThreadWithException, self).__init__(*args, **kwargs)
39
 
        self.set_ready_event(event)
 
37
            sync_event = threading.Event()
 
38
        super(CatchingExceptionThread, self).__init__(*args, **kwargs)
 
39
        self.set_sync_event(sync_event)
40
40
        self.exception = None
41
41
        self.ignored_exceptions = None # see set_ignored_exceptions
42
42
 
44
44
    if sys.version_info < (2, 6):
45
45
        name = property(threading.Thread.getName, threading.Thread.setName)
46
46
 
47
 
    def set_ready_event(self, event):
48
 
        """Set the ``ready`` event used to synchronize exception catching.
 
47
    def set_sync_event(self, event):
 
48
        """Set the ``sync_event`` event used to synchronize exception catching.
49
49
 
50
50
        When the thread uses an event to synchronize itself with another thread
51
51
        (setting it when the other thread can wake up from a ``wait`` call),
54
54
 
55
55
        Some threads require multiple events and should set the relevant one
56
56
        when appropriate.
 
57
 
 
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.
57
60
        """
58
 
        self.ready = event
 
61
        self.sync_event = event
59
62
 
60
63
    def set_ignored_exceptions(self, ignored):
61
64
        """Declare which exceptions will be ignored.
77
80
 
78
81
    def run(self):
79
82
        """Overrides Thread.run to capture any exception."""
80
 
        self.ready.clear()
 
83
        self.sync_event.clear()
81
84
        try:
82
85
            try:
83
 
                super(ThreadWithException, self).run()
 
86
                super(CatchingExceptionThread, self).run()
84
87
            except:
85
88
                self.exception = sys.exc_info()
86
89
        finally:
87
90
            # Make sure the calling thread is released
88
 
            self.ready.set()
89
 
 
90
 
 
91
 
    def join(self, timeout=5):
 
91
            self.sync_event.set()
 
92
 
 
93
 
 
94
    def join(self, timeout=None):
92
95
        """Overrides Thread.join to raise any exception caught.
93
96
 
94
 
 
95
97
        Calling join(timeout=0) will raise the caught exception or return None
96
98
        if the thread is still alive.
97
 
 
98
 
        The default timeout is set to 5 and should expire only when a thread
99
 
        serving a client connection is hung.
100
99
        """
101
 
        super(ThreadWithException, self).join(timeout)
 
100
        super(CatchingExceptionThread, self).join(timeout)
102
101
        if self.exception is not None:
103
102
            exc_class, exc_value, exc_tb = self.exception
104
103
            self.exception = None # The exception should be raised only once