| 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 |