OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 #include <dirent.h> | 5 #include <dirent.h> |
6 #include <errno.h> | 6 #include <errno.h> |
7 #include <fcntl.h> | 7 #include <fcntl.h> |
8 #include <signal.h> | 8 #include <signal.h> |
9 #include <stdlib.h> | 9 #include <stdlib.h> |
10 #include <sys/resource.h> | 10 #include <sys/resource.h> |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
177 return true; | 177 return true; |
178 } | 178 } |
179 | 179 |
180 // If it didn't exit cleanly, it must have been signaled. | 180 // If it didn't exit cleanly, it must have been signaled. |
181 DCHECK(WIFSIGNALED(status)); | 181 DCHECK(WIFSIGNALED(status)); |
182 return false; | 182 return false; |
183 } | 183 } |
184 | 184 |
185 namespace { | 185 namespace { |
186 | 186 |
187 int WaitpidWithTimeout(ProcessHandle handle, int wait_milliseconds) { | 187 int WaitpidWithTimeout(ProcessHandle handle, int wait_milliseconds, |
| 188 bool* success) { |
188 // This POSIX version of this function only guarantees that we wait no less | 189 // This POSIX version of this function only guarantees that we wait no less |
189 // than |wait_milliseconds| for the proces to exit. The child process may | 190 // than |wait_milliseconds| for the proces to exit. The child process may |
190 // exit sometime before the timeout has ended but we may still block for | 191 // exit sometime before the timeout has ended but we may still block for |
191 // up to 0.25 seconds after the fact. | 192 // up to 0.25 seconds after the fact. |
192 // | 193 // |
193 // waitpid() has no direct support on POSIX for specifying a timeout, you can | 194 // waitpid() has no direct support on POSIX for specifying a timeout, you can |
194 // either ask it to block indefinitely or return immediately (WNOHANG). | 195 // either ask it to block indefinitely or return immediately (WNOHANG). |
195 // When a child process terminates a SIGCHLD signal is sent to the parent. | 196 // When a child process terminates a SIGCHLD signal is sent to the parent. |
196 // Catching this signal would involve installing a signal handler which may | 197 // Catching this signal would involve installing a signal handler which may |
197 // affect other parts of the application and would be difficult to debug. | 198 // affect other parts of the application and would be difficult to debug. |
(...skipping 25 matching lines...) Expand all Loading... |
223 if (sleep_time_usecs > kQuarterSecondInMicroseconds) { | 224 if (sleep_time_usecs > kQuarterSecondInMicroseconds) { |
224 sleep_time_usecs = kQuarterSecondInMicroseconds; | 225 sleep_time_usecs = kQuarterSecondInMicroseconds; |
225 } | 226 } |
226 | 227 |
227 // usleep() will return 0 and set errno to EINTR on receipt of a signal | 228 // usleep() will return 0 and set errno to EINTR on receipt of a signal |
228 // such as SIGCHLD. | 229 // such as SIGCHLD. |
229 usleep(sleep_time_usecs); | 230 usleep(sleep_time_usecs); |
230 ret_pid = waitpid(handle, &status, WNOHANG); | 231 ret_pid = waitpid(handle, &status, WNOHANG); |
231 } | 232 } |
232 | 233 |
| 234 if (success) |
| 235 *success = (ret_pid != -1); |
| 236 |
233 return status; | 237 return status; |
234 } | 238 } |
235 | 239 |
236 } // namespace | 240 } // namespace |
237 | 241 |
238 bool WaitForSingleProcess(ProcessHandle handle, int wait_milliseconds) { | 242 bool WaitForSingleProcess(ProcessHandle handle, int wait_milliseconds) { |
239 int status = WaitpidWithTimeout(handle, wait_milliseconds); | 243 bool waitpid_success; |
240 if (status != -1) | 244 int status = WaitpidWithTimeout(handle, wait_milliseconds, &waitpid_success); |
| 245 if (status != -1) { |
| 246 DCHECK(waitpid_success); |
241 return WIFEXITED(status); | 247 return WIFEXITED(status); |
242 else | 248 } else { |
243 return false; | 249 return false; |
| 250 } |
244 } | 251 } |
245 | 252 |
246 bool CrashAwareSleep(ProcessHandle handle, int wait_milliseconds) { | 253 bool CrashAwareSleep(ProcessHandle handle, int wait_milliseconds) { |
247 int status = WaitpidWithTimeout(handle, wait_milliseconds); | 254 bool waitpid_success; |
248 if (status != -1) | 255 int status = WaitpidWithTimeout(handle, wait_milliseconds, &waitpid_success); |
| 256 if (status != -1) { |
| 257 DCHECK(waitpid_success); |
249 return !(WIFEXITED(status) || WIFSIGNALED(status)); | 258 return !(WIFEXITED(status) || WIFSIGNALED(status)); |
250 else | 259 } else { |
251 return true; | 260 // If waitpid returned with an error, then the process doesn't exist |
| 261 // (which most probably means it didn't exist before our call). |
| 262 return waitpid_success; |
| 263 } |
252 } | 264 } |
253 | 265 |
254 namespace { | 266 namespace { |
255 | 267 |
256 int64 TimeValToMicroseconds(const struct timeval& tv) { | 268 int64 TimeValToMicroseconds(const struct timeval& tv) { |
257 return tv.tv_sec * kMicrosecondsPerSecond + tv.tv_usec; | 269 return tv.tv_sec * kMicrosecondsPerSecond + tv.tv_usec; |
258 } | 270 } |
259 | 271 |
260 } | 272 } |
261 | 273 |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
348 const ProcessFilter* filter) { | 360 const ProcessFilter* filter) { |
349 bool exited_cleanly = | 361 bool exited_cleanly = |
350 WaitForProcessesToExit(executable_name, wait_milliseconds, | 362 WaitForProcessesToExit(executable_name, wait_milliseconds, |
351 filter); | 363 filter); |
352 if (!exited_cleanly) | 364 if (!exited_cleanly) |
353 KillProcesses(executable_name, exit_code, filter); | 365 KillProcesses(executable_name, exit_code, filter); |
354 return exited_cleanly; | 366 return exited_cleanly; |
355 } | 367 } |
356 | 368 |
357 } // namespace base | 369 } // namespace base |
OLD | NEW |