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

Unified Diff: base/process/kill_posix.cc

Issue 938453002: Remove base::WaitForSingleProcess (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: cl format :( Created 5 years, 10 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « base/process/kill.h ('k') | base/process/kill_win.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/process/kill_posix.cc
diff --git a/base/process/kill_posix.cc b/base/process/kill_posix.cc
index 5e8b61f6b86be7eb6ddc11ce503f733c37a74b8c..77705eeb6789b0a53a81ae11c468b2270e3a736e 100644
--- a/base/process/kill_posix.cc
+++ b/base/process/kill_posix.cc
@@ -84,6 +84,97 @@ bool WaitpidWithTimeout(ProcessHandle handle,
return ret_pid > 0;
}
+
+#if defined(OS_MACOSX)
+// Using kqueue on Mac so that we can wait on non-child processes.
+// We can't use kqueues on child processes because we need to reap
+// our own children using wait.
+static bool WaitForSingleNonChildProcess(ProcessHandle handle,
+ TimeDelta wait) {
+ DCHECK_GT(handle, 0);
+ DCHECK(wait.InMilliseconds() == kNoTimeout || wait > TimeDelta());
+
+ ScopedFD kq(kqueue());
+ if (!kq.is_valid()) {
+ DPLOG(ERROR) << "kqueue";
+ return false;
+ }
+
+ struct kevent change = {0};
+ EV_SET(&change, handle, EVFILT_PROC, EV_ADD, NOTE_EXIT, 0, NULL);
+ int result = HANDLE_EINTR(kevent(kq.get(), &change, 1, NULL, 0, NULL));
+ if (result == -1) {
+ if (errno == ESRCH) {
+ // If the process wasn't found, it must be dead.
+ return true;
+ }
+
+ DPLOG(ERROR) << "kevent (setup " << handle << ")";
+ return false;
+ }
+
+ // Keep track of the elapsed time to be able to restart kevent if it's
+ // interrupted.
+ bool wait_forever = wait.InMilliseconds() == kNoTimeout;
+ TimeDelta remaining_delta;
+ TimeTicks deadline;
+ if (!wait_forever) {
+ remaining_delta = wait;
+ deadline = TimeTicks::Now() + remaining_delta;
+ }
+
+ result = -1;
+ struct kevent event = {0};
+
+ while (wait_forever || remaining_delta > TimeDelta()) {
+ struct timespec remaining_timespec;
+ struct timespec* remaining_timespec_ptr;
+ if (wait_forever) {
+ remaining_timespec_ptr = NULL;
+ } else {
+ remaining_timespec = remaining_delta.ToTimeSpec();
+ remaining_timespec_ptr = &remaining_timespec;
+ }
+
+ result = kevent(kq.get(), NULL, 0, &event, 1, remaining_timespec_ptr);
+
+ if (result == -1 && errno == EINTR) {
+ if (!wait_forever) {
+ remaining_delta = deadline - TimeTicks::Now();
+ }
+ result = 0;
+ } else {
+ break;
+ }
+ }
+
+ if (result < 0) {
+ DPLOG(ERROR) << "kevent (wait " << handle << ")";
+ return false;
+ } else if (result > 1) {
+ DLOG(ERROR) << "kevent (wait " << handle << "): unexpected result "
+ << result;
+ return false;
+ } else if (result == 0) {
+ // Timed out.
+ return false;
+ }
+
+ DCHECK_EQ(result, 1);
+
+ if (event.filter != EVFILT_PROC ||
+ (event.fflags & NOTE_EXIT) == 0 ||
+ event.ident != static_cast<uintptr_t>(handle)) {
+ DLOG(ERROR) << "kevent (wait " << handle
+ << "): unexpected event: filter=" << event.filter
+ << ", fflags=" << event.fflags
+ << ", ident=" << event.ident;
+ return false;
+ }
+
+ return true;
+}
+#endif // OS_MACOSX
#endif // !defined(OS_NACL_NONSFI)
TerminationStatus GetTerminationStatusImpl(ProcessHandle handle,
@@ -230,7 +321,19 @@ bool WaitForExitCode(ProcessHandle handle, int* exit_code) {
bool WaitForExitCodeWithTimeout(ProcessHandle handle,
int* exit_code,
- base::TimeDelta timeout) {
+ TimeDelta timeout) {
+ ProcessHandle parent_pid = GetParentProcessId(handle);
+ ProcessHandle our_pid = GetCurrentProcessHandle();
+ if (parent_pid != our_pid) {
+#if defined(OS_MACOSX)
+ // On Mac we can wait on non child processes.
+ return WaitForSingleNonChildProcess(handle, timeout);
+#else
+ // Currently on Linux we can't handle non child processes.
+ NOTIMPLEMENTED();
+#endif // OS_MACOSX
+ }
+
int status;
if (!WaitpidWithTimeout(handle, &status, timeout))
return false;
@@ -246,138 +349,28 @@ bool WaitForExitCodeWithTimeout(ProcessHandle handle,
}
bool WaitForProcessesToExit(const FilePath::StringType& executable_name,
- base::TimeDelta wait,
+ TimeDelta wait,
const ProcessFilter* filter) {
bool result = false;
// TODO(port): This is inefficient, but works if there are multiple procs.
// TODO(port): use waitpid to avoid leaving zombies around
- base::TimeTicks end_time = base::TimeTicks::Now() + wait;
+ TimeTicks end_time = TimeTicks::Now() + wait;
do {
NamedProcessIterator iter(executable_name, filter);
if (!iter.NextProcessEntry()) {
result = true;
break;
}
- base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(100));
- } while ((end_time - base::TimeTicks::Now()) > base::TimeDelta());
+ PlatformThread::Sleep(TimeDelta::FromMilliseconds(100));
+ } while ((end_time - TimeTicks::Now()) > TimeDelta());
return result;
}
-#if defined(OS_MACOSX)
-// Using kqueue on Mac so that we can wait on non-child processes.
-// We can't use kqueues on child processes because we need to reap
-// our own children using wait.
-static bool WaitForSingleNonChildProcess(ProcessHandle handle,
- base::TimeDelta wait) {
- DCHECK_GT(handle, 0);
- DCHECK(wait.InMilliseconds() == base::kNoTimeout || wait > base::TimeDelta());
-
- ScopedFD kq(kqueue());
- if (!kq.is_valid()) {
- DPLOG(ERROR) << "kqueue";
- return false;
- }
-
- struct kevent change = {0};
- EV_SET(&change, handle, EVFILT_PROC, EV_ADD, NOTE_EXIT, 0, NULL);
- int result = HANDLE_EINTR(kevent(kq.get(), &change, 1, NULL, 0, NULL));
- if (result == -1) {
- if (errno == ESRCH) {
- // If the process wasn't found, it must be dead.
- return true;
- }
-
- DPLOG(ERROR) << "kevent (setup " << handle << ")";
- return false;
- }
-
- // Keep track of the elapsed time to be able to restart kevent if it's
- // interrupted.
- bool wait_forever = wait.InMilliseconds() == base::kNoTimeout;
- base::TimeDelta remaining_delta;
- base::TimeTicks deadline;
- if (!wait_forever) {
- remaining_delta = wait;
- deadline = base::TimeTicks::Now() + remaining_delta;
- }
-
- result = -1;
- struct kevent event = {0};
-
- while (wait_forever || remaining_delta > base::TimeDelta()) {
- struct timespec remaining_timespec;
- struct timespec* remaining_timespec_ptr;
- if (wait_forever) {
- remaining_timespec_ptr = NULL;
- } else {
- remaining_timespec = remaining_delta.ToTimeSpec();
- remaining_timespec_ptr = &remaining_timespec;
- }
-
- result = kevent(kq.get(), NULL, 0, &event, 1, remaining_timespec_ptr);
-
- if (result == -1 && errno == EINTR) {
- if (!wait_forever) {
- remaining_delta = deadline - base::TimeTicks::Now();
- }
- result = 0;
- } else {
- break;
- }
- }
-
- if (result < 0) {
- DPLOG(ERROR) << "kevent (wait " << handle << ")";
- return false;
- } else if (result > 1) {
- DLOG(ERROR) << "kevent (wait " << handle << "): unexpected result "
- << result;
- return false;
- } else if (result == 0) {
- // Timed out.
- return false;
- }
-
- DCHECK_EQ(result, 1);
-
- if (event.filter != EVFILT_PROC ||
- (event.fflags & NOTE_EXIT) == 0 ||
- event.ident != static_cast<uintptr_t>(handle)) {
- DLOG(ERROR) << "kevent (wait " << handle
- << "): unexpected event: filter=" << event.filter
- << ", fflags=" << event.fflags
- << ", ident=" << event.ident;
- return false;
- }
-
- return true;
-}
-#endif // OS_MACOSX
-
-bool WaitForSingleProcess(ProcessHandle handle, base::TimeDelta wait) {
- ProcessHandle parent_pid = GetParentProcessId(handle);
- ProcessHandle our_pid = GetCurrentProcessHandle();
- if (parent_pid != our_pid) {
-#if defined(OS_MACOSX)
- // On Mac we can wait on non child processes.
- return WaitForSingleNonChildProcess(handle, wait);
-#else
- // Currently on Linux we can't handle non child processes.
- NOTIMPLEMENTED();
-#endif // OS_MACOSX
- }
-
- int status;
- if (!WaitpidWithTimeout(handle, &status, wait))
- return false;
- return WIFEXITED(status);
-}
-
bool CleanupProcesses(const FilePath::StringType& executable_name,
- base::TimeDelta wait,
+ TimeDelta wait,
int exit_code,
const ProcessFilter* filter) {
bool exited_cleanly = WaitForProcessesToExit(executable_name, wait, filter);
« no previous file with comments | « base/process/kill.h ('k') | base/process/kill_win.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698