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

Side by Side Diff: third_party/android_testrunner/run_command.py

Issue 13047009: [Android] Fix a race condition in run_command.py. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 8 months 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 | Annotate | Revision Log
« no previous file with comments | « third_party/android_testrunner/patch.diff ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/python2.4 1 #!/usr/bin/python2.4
2 # 2 #
3 # 3 #
4 # Copyright 2007, The Android Open Source Project 4 # Copyright 2007, The Android Open Source Project
5 # 5 #
6 # Licensed under the Apache License, Version 2.0 (the "License"); 6 # Licensed under the Apache License, Version 2.0 (the "License");
7 # you may not use this file except in compliance with the License. 7 # you may not use this file except in compliance with the License.
8 # You may obtain a copy of the License at 8 # You may obtain a copy of the License at
9 # 9 #
10 # http://www.apache.org/licenses/LICENSE-2.0 10 # http://www.apache.org/licenses/LICENSE-2.0
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
73 stdin_input: data to feed to stdin 73 stdin_input: data to feed to stdin
74 Returns: 74 Returns:
75 output of command 75 output of command
76 Raises: 76 Raises:
77 errors.WaitForResponseTimedOutError if command did not complete within 77 errors.WaitForResponseTimedOutError if command did not complete within
78 timeout_time seconds. 78 timeout_time seconds.
79 errors.AbortError is command returned error code and SetAbortOnError is on. 79 errors.AbortError is command returned error code and SetAbortOnError is on.
80 """ 80 """
81 start_time = time.time() 81 start_time = time.time()
82 so = [] 82 so = []
83 pid = []
84 global _abort_on_error, error_occurred 83 global _abort_on_error, error_occurred
85 error_occurred = False 84 error_occurred = False
86 85
86 if return_output:
87 output_dest = subprocess.PIPE
88 else:
89 # None means direct to stdout
90 output_dest = None
91 if stdin_input:
92 stdin_dest = subprocess.PIPE
93 else:
94 stdin_dest = None
95 pipe = subprocess.Popen(
96 cmd,
97 executable='/bin/bash',
98 stdin=stdin_dest,
99 stdout=output_dest,
100 stderr=subprocess.STDOUT,
101 shell=True)
102
87 def Run(): 103 def Run():
88 global error_occurred 104 global error_occurred
89 if return_output:
90 output_dest = subprocess.PIPE
91 else:
92 # None means direct to stdout
93 output_dest = None
94 if stdin_input:
95 stdin_dest = subprocess.PIPE
96 else:
97 stdin_dest = None
98 pipe = subprocess.Popen(
99 cmd,
100 executable='/bin/bash',
101 stdin=stdin_dest,
102 stdout=output_dest,
103 stderr=subprocess.STDOUT,
104 shell=True)
105 pid.append(pipe.pid)
106 try: 105 try:
107 output = pipe.communicate(input=stdin_input)[0] 106 output = pipe.communicate(input=stdin_input)[0]
108 if output is not None and len(output) > 0: 107 if output is not None and len(output) > 0:
109 so.append(output) 108 so.append(output)
110 except OSError, e: 109 except OSError, e:
111 logger.SilentLog("failed to retrieve stdout from: %s" % cmd) 110 logger.SilentLog("failed to retrieve stdout from: %s" % cmd)
112 logger.Log(e) 111 logger.Log(e)
113 so.append("ERROR") 112 so.append("ERROR")
114 error_occurred = True 113 error_occurred = True
115 if pipe.returncode: 114 if pipe.returncode:
116 logger.SilentLog("Error: %s returned %d error code" %(cmd, 115 logger.SilentLog("Error: %s returned %d error code" %(cmd,
117 pipe.returncode)) 116 pipe.returncode))
118 error_occurred = True 117 error_occurred = True
119 118
120 t = threading.Thread(target=Run) 119 t = threading.Thread(target=Run)
121 t.start() 120 t.start()
122 121 t.join(timeout_time)
123 break_loop = False 122 if t.isAlive():
124 while not break_loop: 123 try:
125 if not t.isAlive(): 124 pipe.kill()
126 break_loop = True 125 except OSError:
127 126 # Can't kill a dead process.
128 # Check the timeout 127 pass
129 if (not break_loop and timeout_time is not None 128 finally:
130 and time.time() > start_time + timeout_time):
131 try:
132 os.kill(pid[0], signal.SIGKILL)
133 except OSError:
134 # process already dead. No action required.
135 pass
136
137 logger.SilentLog("about to raise a timeout for: %s" % cmd) 129 logger.SilentLog("about to raise a timeout for: %s" % cmd)
138 raise errors.WaitForResponseTimedOutError 130 raise errors.WaitForResponseTimedOutError
139 if not break_loop:
140 time.sleep(0.1)
141 131
142 t.join()
143 output = "".join(so) 132 output = "".join(so)
144 if _abort_on_error and error_occurred: 133 if _abort_on_error and error_occurred:
145 raise errors.AbortError(msg=output) 134 raise errors.AbortError(msg=output)
146 135
147 return "".join(so) 136 return "".join(so)
148 137
149 138
150 def RunHostCommand(binary, valgrind=False): 139 def RunHostCommand(binary, valgrind=False):
151 """Run a command on the host (opt using valgrind). 140 """Run a command on the host (opt using valgrind).
152 141
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
187 def HasValgrind(): 176 def HasValgrind():
188 """Check that /usr/bin/valgrind exists. 177 """Check that /usr/bin/valgrind exists.
189 178
190 We look for the fullpath to avoid picking up 'alternative' valgrind 179 We look for the fullpath to avoid picking up 'alternative' valgrind
191 on the system. 180 on the system.
192 181
193 Returns: 182 Returns:
194 True if a system valgrind was found. 183 True if a system valgrind was found.
195 """ 184 """
196 return os.path.exists("/usr/bin/valgrind") 185 return os.path.exists("/usr/bin/valgrind")
OLDNEW
« no previous file with comments | « third_party/android_testrunner/patch.diff ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698