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

Side by Side Diff: base/process/kill_posix.cc

Issue 957183002: Remove base::WaitForExitCode* (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: 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 unified diff | Download patch
OLDNEW
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>
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
43 // waitpid(). The amount of time we sleep starts out at 1 milliseconds, and 43 // waitpid(). The amount of time we sleep starts out at 1 milliseconds, and
44 // we double it every 4 sleep cycles. 44 // we double it every 4 sleep cycles.
45 // 45 //
46 // usleep() is speced to exit if a signal is received for which a handler 46 // usleep() is speced to exit if a signal is received for which a handler
47 // has been installed. This means that when a SIGCHLD is sent, it will exit 47 // has been installed. This means that when a SIGCHLD is sent, it will exit
48 // depending on behavior external to this function. 48 // depending on behavior external to this function.
49 // 49 //
50 // This function is used primarily for unit tests, if we want to use it in 50 // This function is used primarily for unit tests, if we want to use it in
51 // the application itself it would probably be best to examine other routes. 51 // the application itself it would probably be best to examine other routes.
52 52
53 if (wait.InMilliseconds() == base::kNoTimeout) { 53 if (wait.InMilliseconds() == base::internal::kNoTimeout) {
54 return HANDLE_EINTR(waitpid(handle, status, 0)) > 0; 54 return HANDLE_EINTR(waitpid(handle, status, 0)) > 0;
55 } 55 }
56 56
57 pid_t ret_pid = HANDLE_EINTR(waitpid(handle, status, WNOHANG)); 57 pid_t ret_pid = HANDLE_EINTR(waitpid(handle, status, WNOHANG));
58 static const int64 kMaxSleepInMicroseconds = 1 << 18; // ~256 milliseconds. 58 static const int64 kMaxSleepInMicroseconds = 1 << 18; // ~256 milliseconds.
59 int64 max_sleep_time_usecs = 1 << 10; // ~1 milliseconds. 59 int64 max_sleep_time_usecs = 1 << 10; // ~1 milliseconds.
60 int64 double_sleep_time = 0; 60 int64 double_sleep_time = 0;
61 61
62 // If the process hasn't exited yet, then sleep and try again. 62 // If the process hasn't exited yet, then sleep and try again.
63 TimeTicks wakeup_time = TimeTicks::Now() + wait; 63 TimeTicks wakeup_time = TimeTicks::Now() + wait;
(...skipping 21 matching lines...) Expand all
85 return ret_pid > 0; 85 return ret_pid > 0;
86 } 86 }
87 87
88 #if defined(OS_MACOSX) 88 #if defined(OS_MACOSX)
89 // Using kqueue on Mac so that we can wait on non-child processes. 89 // Using kqueue on Mac so that we can wait on non-child processes.
90 // We can't use kqueues on child processes because we need to reap 90 // We can't use kqueues on child processes because we need to reap
91 // our own children using wait. 91 // our own children using wait.
92 static bool WaitForSingleNonChildProcess(ProcessHandle handle, 92 static bool WaitForSingleNonChildProcess(ProcessHandle handle,
93 TimeDelta wait) { 93 TimeDelta wait) {
94 DCHECK_GT(handle, 0); 94 DCHECK_GT(handle, 0);
95 DCHECK(wait.InMilliseconds() == kNoTimeout || wait > TimeDelta()); 95 DCHECK(wait.InMilliseconds() == internal::kNoTimeout || wait > TimeDelta());
96 96
97 ScopedFD kq(kqueue()); 97 ScopedFD kq(kqueue());
98 if (!kq.is_valid()) { 98 if (!kq.is_valid()) {
99 DPLOG(ERROR) << "kqueue"; 99 DPLOG(ERROR) << "kqueue";
100 return false; 100 return false;
101 } 101 }
102 102
103 struct kevent change = {0}; 103 struct kevent change = {0};
104 EV_SET(&change, handle, EVFILT_PROC, EV_ADD, NOTE_EXIT, 0, NULL); 104 EV_SET(&change, handle, EVFILT_PROC, EV_ADD, NOTE_EXIT, 0, NULL);
105 int result = HANDLE_EINTR(kevent(kq.get(), &change, 1, NULL, 0, NULL)); 105 int result = HANDLE_EINTR(kevent(kq.get(), &change, 1, NULL, 0, NULL));
106 if (result == -1) { 106 if (result == -1) {
107 if (errno == ESRCH) { 107 if (errno == ESRCH) {
108 // If the process wasn't found, it must be dead. 108 // If the process wasn't found, it must be dead.
109 return true; 109 return true;
110 } 110 }
111 111
112 DPLOG(ERROR) << "kevent (setup " << handle << ")"; 112 DPLOG(ERROR) << "kevent (setup " << handle << ")";
113 return false; 113 return false;
114 } 114 }
115 115
116 // Keep track of the elapsed time to be able to restart kevent if it's 116 // Keep track of the elapsed time to be able to restart kevent if it's
117 // interrupted. 117 // interrupted.
118 bool wait_forever = wait.InMilliseconds() == kNoTimeout; 118 bool wait_forever = (wait.InMilliseconds() == internal::kNoTimeout);
119 TimeDelta remaining_delta; 119 TimeDelta remaining_delta;
120 TimeTicks deadline; 120 TimeTicks deadline;
121 if (!wait_forever) { 121 if (!wait_forever) {
122 remaining_delta = wait; 122 remaining_delta = wait;
123 deadline = TimeTicks::Now() + remaining_delta; 123 deadline = TimeTicks::Now() + remaining_delta;
124 } 124 }
125 125
126 result = -1; 126 result = -1;
127 struct kevent event = {0}; 127 struct kevent event = {0};
128 128
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
295 int* exit_code) { 295 int* exit_code) {
296 bool result = kill(handle, SIGKILL) == 0; 296 bool result = kill(handle, SIGKILL) == 0;
297 297
298 if (!result) 298 if (!result)
299 DPLOG(ERROR) << "Unable to terminate process " << handle; 299 DPLOG(ERROR) << "Unable to terminate process " << handle;
300 300
301 return GetTerminationStatusImpl(handle, true /* can_block */, exit_code); 301 return GetTerminationStatusImpl(handle, true /* can_block */, exit_code);
302 } 302 }
303 303
304 #if !defined(OS_NACL_NONSFI) 304 #if !defined(OS_NACL_NONSFI)
305 bool WaitForExitCode(ProcessHandle handle, int* exit_code) { 305 bool internal::WaitForExitCodeWithTimeout(ProcessHandle handle,
306 int status; 306 int* exit_code,
307 if (HANDLE_EINTR(waitpid(handle, &status, 0)) == -1) { 307 TimeDelta timeout) {
308 NOTREACHED();
309 return false;
310 }
311
312 if (WIFEXITED(status)) {
313 *exit_code = WEXITSTATUS(status);
314 return true;
315 }
316
317 // If it didn't exit cleanly, it must have been signaled.
318 DCHECK(WIFSIGNALED(status));
319 return false;
320 }
321
322 bool WaitForExitCodeWithTimeout(ProcessHandle handle,
323 int* exit_code,
324 TimeDelta timeout) {
325 ProcessHandle parent_pid = GetParentProcessId(handle); 308 ProcessHandle parent_pid = GetParentProcessId(handle);
326 ProcessHandle our_pid = GetCurrentProcessHandle(); 309 ProcessHandle our_pid = GetCurrentProcessHandle();
327 if (parent_pid != our_pid) { 310 if (parent_pid != our_pid) {
328 #if defined(OS_MACOSX) 311 #if defined(OS_MACOSX)
329 // On Mac we can wait on non child processes. 312 // On Mac we can wait on non child processes.
330 return WaitForSingleNonChildProcess(handle, timeout); 313 return WaitForSingleNonChildProcess(handle, timeout);
331 #else 314 #else
332 // Currently on Linux we can't handle non child processes. 315 // Currently on Linux we can't handle non child processes.
333 NOTIMPLEMENTED(); 316 NOTIMPLEMENTED();
334 #endif // OS_MACOSX 317 #endif // OS_MACOSX
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
472 return; 455 return;
473 456
474 BackgroundReaper* reaper = new BackgroundReaper(pid, 0); 457 BackgroundReaper* reaper = new BackgroundReaper(pid, 0);
475 PlatformThread::CreateNonJoinable(0, reaper); 458 PlatformThread::CreateNonJoinable(0, reaper);
476 } 459 }
477 460
478 #endif // !defined(OS_MACOSX) 461 #endif // !defined(OS_MACOSX)
479 #endif // !defined(OS_NACL_NONSFI) 462 #endif // !defined(OS_NACL_NONSFI)
480 463
481 } // namespace base 464 } // namespace base
OLDNEW
« base/process/kill.h ('K') | « 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