OLD | NEW |
1 # Copyright 2013 The Chromium Authors. All rights reserved. | 1 # Copyright 2013 The Chromium Authors. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 """Thread and ThreadGroup that reraise exceptions on the main thread.""" | 5 """Thread and ThreadGroup that reraise exceptions on the main thread.""" |
6 # pylint: disable=W0212 | 6 # pylint: disable=W0212 |
7 | 7 |
8 import logging | 8 import logging |
9 import sys | 9 import sys |
10 import threading | 10 import threading |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
49 """ | 49 """ |
50 super(ReraiserThread, self).__init__(name=name) | 50 super(ReraiserThread, self).__init__(name=name) |
51 if not args: | 51 if not args: |
52 args = [] | 52 args = [] |
53 if not kwargs: | 53 if not kwargs: |
54 kwargs = {} | 54 kwargs = {} |
55 self.daemon = True | 55 self.daemon = True |
56 self._func = func | 56 self._func = func |
57 self._args = args | 57 self._args = args |
58 self._kwargs = kwargs | 58 self._kwargs = kwargs |
| 59 self._ret = None |
59 self._exc_info = None | 60 self._exc_info = None |
60 | 61 |
61 def ReraiseIfException(self): | 62 def ReraiseIfException(self): |
62 """Reraise exception if an exception was raised in the thread.""" | 63 """Reraise exception if an exception was raised in the thread.""" |
63 if self._exc_info: | 64 if self._exc_info: |
64 raise self._exc_info[0], self._exc_info[1], self._exc_info[2] | 65 raise self._exc_info[0], self._exc_info[1], self._exc_info[2] |
65 | 66 |
| 67 def GetReturnValue(self): |
| 68 """Reraise exception if present, otherwise get the return value.""" |
| 69 self.ReraiseIfException() |
| 70 return self._ret |
| 71 |
66 #override | 72 #override |
67 def run(self): | 73 def run(self): |
68 """Overrides Thread.run() to add support for reraising exceptions.""" | 74 """Overrides Thread.run() to add support for reraising exceptions.""" |
69 try: | 75 try: |
70 self._func(*self._args, **self._kwargs) | 76 self._ret = self._func(*self._args, **self._kwargs) |
71 except: | 77 except: |
72 self._exc_info = sys.exc_info() | 78 self._exc_info = sys.exc_info() |
73 raise | 79 raise |
74 | 80 |
75 | 81 |
76 class ReraiserThreadGroup(object): | 82 class ReraiserThreadGroup(object): |
77 """A group of ReraiserThread objects.""" | 83 """A group of ReraiserThread objects.""" |
78 | 84 |
79 def __init__(self, threads=None): | 85 def __init__(self, threads=None): |
80 """Initialize thread group. | 86 """Initialize thread group. |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
131 | 137 |
132 Args: | 138 Args: |
133 watcher: Watchdog object providing timeout, by default waits forever. | 139 watcher: Watchdog object providing timeout, by default waits forever. |
134 """ | 140 """ |
135 try: | 141 try: |
136 self._JoinAll(watcher) | 142 self._JoinAll(watcher) |
137 except TimeoutError: | 143 except TimeoutError: |
138 for thread in (t for t in self._threads if t.isAlive()): | 144 for thread in (t for t in self._threads if t.isAlive()): |
139 LogThreadStack(thread) | 145 LogThreadStack(thread) |
140 raise | 146 raise |
| 147 |
| 148 def GetAllReturnValues(self, watcher=watchdog_timer.WatchdogTimer(None)): |
| 149 """Get all return values, joining all threads if necessary. |
| 150 |
| 151 Args: |
| 152 watcher: same as in |JoinAll|. Only used if threads are alive. |
| 153 """ |
| 154 if any([t.isAlive() for t in self._threads]): |
| 155 self.JoinAll(watcher) |
| 156 return [t.GetReturnValue() for t in self._threads] |
| 157 |
OLD | NEW |