Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(315)

Side by Side Diff: build/android/pylib/utils/reraiser_thread.py

Issue 683113005: Update from chromium https://crrev.com/302282 (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « build/android/pylib/utils/isolator.py ('k') | build/android/pylib/utils/timeout_retry.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
11 import traceback 11 import traceback
12 12
13 from pylib.utils import watchdog_timer 13 from pylib.utils import watchdog_timer
14 14
15 15
16 class TimeoutError(Exception): 16 class TimeoutError(Exception):
17 """Module-specific timeout exception.""" 17 """Module-specific timeout exception."""
18 pass 18 pass
19 19
20 20
21 def LogThreadStack(thread): 21 def LogThreadStack(thread):
22 """Log the stack for the given thread. 22 """Log the stack for the given thread.
23 23
24 Args: 24 Args:
25 thread: a threading.Thread instance. 25 thread: a threading.Thread instance.
26 """ 26 """
27 stack = sys._current_frames()[thread.ident] 27 stack = sys._current_frames()[thread.ident]
28 logging.critical('*' * 80) 28 logging.critical('*' * 80)
29 logging.critical('Stack dump for thread \'%s\'', thread.name) 29 logging.critical('Stack dump for thread %r', thread.name)
30 logging.critical('*' * 80) 30 logging.critical('*' * 80)
31 for filename, lineno, name, line in traceback.extract_stack(stack): 31 for filename, lineno, name, line in traceback.extract_stack(stack):
32 logging.critical('File: "%s", line %d, in %s', filename, lineno, name) 32 logging.critical('File: "%s", line %d, in %s', filename, lineno, name)
33 if line: 33 if line:
34 logging.critical(' %s', line.strip()) 34 logging.critical(' %s', line.strip())
35 logging.critical('*' * 80) 35 logging.critical('*' * 80)
36 36
37 37
38 class ReraiserThread(threading.Thread): 38 class ReraiserThread(threading.Thread):
39 """Thread class that can reraise exceptions.""" 39 """Thread class that can reraise exceptions."""
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
97 Args: 97 Args:
98 thread: a ReraiserThread object. 98 thread: a ReraiserThread object.
99 """ 99 """
100 self._threads.append(thread) 100 self._threads.append(thread)
101 101
102 def StartAll(self): 102 def StartAll(self):
103 """Start all threads.""" 103 """Start all threads."""
104 for thread in self._threads: 104 for thread in self._threads:
105 thread.start() 105 thread.start()
106 106
107 def _JoinAll(self, watcher=watchdog_timer.WatchdogTimer(None)): 107 def _JoinAll(self, watcher=None):
108 """Join all threads without stack dumps. 108 """Join all threads without stack dumps.
109 109
110 Reraises exceptions raised by the child threads and supports breaking 110 Reraises exceptions raised by the child threads and supports breaking
111 immediately on exceptions raised on the main thread. 111 immediately on exceptions raised on the main thread.
112 112
113 Args: 113 Args:
114 watcher: Watchdog object providing timeout, by default waits forever. 114 watcher: Watchdog object providing timeout, by default waits forever.
115 """ 115 """
116 if watcher is None:
117 watcher = watchdog_timer.WatchdogTimer(None)
116 alive_threads = self._threads[:] 118 alive_threads = self._threads[:]
117 while alive_threads: 119 while alive_threads:
118 for thread in alive_threads[:]: 120 for thread in alive_threads[:]:
119 if watcher.IsTimedOut(): 121 if watcher.IsTimedOut():
120 raise TimeoutError('Timed out waiting for %d of %d threads.' % 122 raise TimeoutError('Timed out waiting for %d of %d threads.' %
121 (len(alive_threads), len(self._threads))) 123 (len(alive_threads), len(self._threads)))
122 # Allow the main thread to periodically check for interrupts. 124 # Allow the main thread to periodically check for interrupts.
123 thread.join(0.1) 125 thread.join(0.1)
124 if not thread.isAlive(): 126 if not thread.isAlive():
125 alive_threads.remove(thread) 127 alive_threads.remove(thread)
126 # All threads are allowed to complete before reraising exceptions. 128 # All threads are allowed to complete before reraising exceptions.
127 for thread in self._threads: 129 for thread in self._threads:
128 thread.ReraiseIfException() 130 thread.ReraiseIfException()
129 131
130 def JoinAll(self, watcher=watchdog_timer.WatchdogTimer(None)): 132 def JoinAll(self, watcher=None):
131 """Join all threads. 133 """Join all threads.
132 134
133 Reraises exceptions raised by the child threads and supports breaking 135 Reraises exceptions raised by the child threads and supports breaking
134 immediately on exceptions raised on the main thread. Unfinished threads' 136 immediately on exceptions raised on the main thread. Unfinished threads'
135 stacks will be logged on watchdog timeout. 137 stacks will be logged on watchdog timeout.
136 138
137 Args: 139 Args:
138 watcher: Watchdog object providing timeout, by default waits forever. 140 watcher: Watchdog object providing timeout, by default waits forever.
139 """ 141 """
140 try: 142 try:
141 self._JoinAll(watcher) 143 self._JoinAll(watcher)
142 except TimeoutError: 144 except TimeoutError:
143 for thread in (t for t in self._threads if t.isAlive()): 145 for thread in (t for t in self._threads if t.isAlive()):
144 LogThreadStack(thread) 146 LogThreadStack(thread)
145 raise 147 raise
146 148
147 def GetAllReturnValues(self, watcher=watchdog_timer.WatchdogTimer(None)): 149 def GetAllReturnValues(self, watcher=None):
148 """Get all return values, joining all threads if necessary. 150 """Get all return values, joining all threads if necessary.
149 151
150 Args: 152 Args:
151 watcher: same as in |JoinAll|. Only used if threads are alive. 153 watcher: same as in |JoinAll|. Only used if threads are alive.
152 """ 154 """
153 if any([t.isAlive() for t in self._threads]): 155 if any([t.isAlive() for t in self._threads]):
154 self.JoinAll(watcher) 156 self.JoinAll(watcher)
155 return [t.GetReturnValue() for t in self._threads] 157 return [t.GetReturnValue() for t in self._threads]
156 158
OLDNEW
« no previous file with comments | « build/android/pylib/utils/isolator.py ('k') | build/android/pylib/utils/timeout_retry.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698