OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 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 #include "base/process/kill.h" | 5 #include "base/process/kill.h" |
6 | 6 |
7 #include <signal.h> | 7 #include <signal.h> |
8 #include <sys/types.h> | 8 #include <sys/types.h> |
9 #include <sys/wait.h> | 9 #include <sys/wait.h> |
10 #include <unistd.h> | 10 #include <unistd.h> |
11 | 11 |
12 #include "base/file_util.h" | 12 #include "base/file_util.h" |
13 #include "base/files/scoped_file.h" | |
14 #include "base/logging.h" | 13 #include "base/logging.h" |
15 #include "base/posix/eintr_wrapper.h" | 14 #include "base/posix/eintr_wrapper.h" |
16 #include "base/process/process_iterator.h" | 15 #include "base/process/process_iterator.h" |
17 #include "base/synchronization/waitable_event.h" | 16 #include "base/synchronization/waitable_event.h" |
18 #include "base/third_party/dynamic_annotations/dynamic_annotations.h" | 17 #include "base/third_party/dynamic_annotations/dynamic_annotations.h" |
19 #include "base/threading/platform_thread.h" | 18 #include "base/threading/platform_thread.h" |
20 | 19 |
21 namespace base { | 20 namespace base { |
22 | 21 |
23 namespace { | 22 namespace { |
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
267 | 266 |
268 #if defined(OS_MACOSX) | 267 #if defined(OS_MACOSX) |
269 // Using kqueue on Mac so that we can wait on non-child processes. | 268 // Using kqueue on Mac so that we can wait on non-child processes. |
270 // We can't use kqueues on child processes because we need to reap | 269 // We can't use kqueues on child processes because we need to reap |
271 // our own children using wait. | 270 // our own children using wait. |
272 static bool WaitForSingleNonChildProcess(ProcessHandle handle, | 271 static bool WaitForSingleNonChildProcess(ProcessHandle handle, |
273 base::TimeDelta wait) { | 272 base::TimeDelta wait) { |
274 DCHECK_GT(handle, 0); | 273 DCHECK_GT(handle, 0); |
275 DCHECK(wait.InMilliseconds() == base::kNoTimeout || wait > base::TimeDelta()); | 274 DCHECK(wait.InMilliseconds() == base::kNoTimeout || wait > base::TimeDelta()); |
276 | 275 |
277 ScopedFD kq(kqueue()); | 276 int kq = kqueue(); |
278 if (!kq.is_valid()) { | 277 if (kq == -1) { |
279 DPLOG(ERROR) << "kqueue"; | 278 DPLOG(ERROR) << "kqueue"; |
280 return false; | 279 return false; |
281 } | 280 } |
| 281 file_util::ScopedFD kq_closer(&kq); |
282 | 282 |
283 struct kevent change = {0}; | 283 struct kevent change = {0}; |
284 EV_SET(&change, handle, EVFILT_PROC, EV_ADD, NOTE_EXIT, 0, NULL); | 284 EV_SET(&change, handle, EVFILT_PROC, EV_ADD, NOTE_EXIT, 0, NULL); |
285 int result = HANDLE_EINTR(kevent(kq.get(), &change, 1, NULL, 0, NULL)); | 285 int result = HANDLE_EINTR(kevent(kq, &change, 1, NULL, 0, NULL)); |
286 if (result == -1) { | 286 if (result == -1) { |
287 if (errno == ESRCH) { | 287 if (errno == ESRCH) { |
288 // If the process wasn't found, it must be dead. | 288 // If the process wasn't found, it must be dead. |
289 return true; | 289 return true; |
290 } | 290 } |
291 | 291 |
292 DPLOG(ERROR) << "kevent (setup " << handle << ")"; | 292 DPLOG(ERROR) << "kevent (setup " << handle << ")"; |
293 return false; | 293 return false; |
294 } | 294 } |
295 | 295 |
(...skipping 13 matching lines...) Expand all Loading... |
309 while (wait_forever || remaining_delta > base::TimeDelta()) { | 309 while (wait_forever || remaining_delta > base::TimeDelta()) { |
310 struct timespec remaining_timespec; | 310 struct timespec remaining_timespec; |
311 struct timespec* remaining_timespec_ptr; | 311 struct timespec* remaining_timespec_ptr; |
312 if (wait_forever) { | 312 if (wait_forever) { |
313 remaining_timespec_ptr = NULL; | 313 remaining_timespec_ptr = NULL; |
314 } else { | 314 } else { |
315 remaining_timespec = remaining_delta.ToTimeSpec(); | 315 remaining_timespec = remaining_delta.ToTimeSpec(); |
316 remaining_timespec_ptr = &remaining_timespec; | 316 remaining_timespec_ptr = &remaining_timespec; |
317 } | 317 } |
318 | 318 |
319 result = kevent(kq.get(), NULL, 0, &event, 1, remaining_timespec_ptr); | 319 result = kevent(kq, NULL, 0, &event, 1, remaining_timespec_ptr); |
320 | 320 |
321 if (result == -1 && errno == EINTR) { | 321 if (result == -1 && errno == EINTR) { |
322 if (!wait_forever) { | 322 if (!wait_forever) { |
323 remaining_delta = deadline - base::TimeTicks::Now(); | 323 remaining_delta = deadline - base::TimeTicks::Now(); |
324 } | 324 } |
325 result = 0; | 325 result = 0; |
326 } else { | 326 } else { |
327 break; | 327 break; |
328 } | 328 } |
329 } | 329 } |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
488 if (IsChildDead(process)) | 488 if (IsChildDead(process)) |
489 return; | 489 return; |
490 | 490 |
491 BackgroundReaper* reaper = new BackgroundReaper(process, 0); | 491 BackgroundReaper* reaper = new BackgroundReaper(process, 0); |
492 PlatformThread::CreateNonJoinable(0, reaper); | 492 PlatformThread::CreateNonJoinable(0, reaper); |
493 } | 493 } |
494 | 494 |
495 #endif // !defined(OS_MACOSX) | 495 #endif // !defined(OS_MACOSX) |
496 | 496 |
497 } // namespace base | 497 } // namespace base |
OLD | NEW |