| OLD | NEW |
| 1 // Copyright (c) 2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 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 "base/process_util.h" | 5 #include "base/process_util.h" |
| 6 | 6 |
| 7 #include <ctype.h> | 7 #include <ctype.h> |
| 8 #include <dirent.h> | 8 #include <dirent.h> |
| 9 #include <fcntl.h> | 9 #include <fcntl.h> |
| 10 #include <unistd.h> | 10 #include <unistd.h> |
| 11 #include <string> | 11 #include <string> |
| 12 #include <sys/types.h> | 12 #include <sys/types.h> |
| 13 #include <sys/wait.h> | 13 #include <sys/wait.h> |
| 14 | 14 |
| 15 #include "base/file_util.h" | 15 #include "base/file_util.h" |
| 16 #include "base/logging.h" | 16 #include "base/logging.h" |
| 17 #include "base/platform_thread.h" | |
| 18 #include "base/string_tokenizer.h" | 17 #include "base/string_tokenizer.h" |
| 19 #include "base/string_util.h" | 18 #include "base/string_util.h" |
| 20 #include "base/time.h" | 19 #include "base/time.h" |
| 21 | 20 |
| 22 namespace { | 21 namespace { |
| 23 | 22 |
| 24 enum ParsingState { | 23 enum ParsingState { |
| 25 KEY_NAME, | 24 KEY_NAME, |
| 26 KEY_VALUE | 25 KEY_VALUE |
| 27 }; | 26 }; |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 195 | 194 |
| 196 bool NamedProcessIterator::IncludeEntry() { | 195 bool NamedProcessIterator::IncludeEntry() { |
| 197 // TODO(port): make this also work for non-ASCII filenames | 196 // TODO(port): make this also work for non-ASCII filenames |
| 198 if (WideToASCII(executable_name_) != entry_.szExeFile) | 197 if (WideToASCII(executable_name_) != entry_.szExeFile) |
| 199 return false; | 198 return false; |
| 200 if (!filter_) | 199 if (!filter_) |
| 201 return true; | 200 return true; |
| 202 return filter_->Includes(entry_.pid, entry_.ppid); | 201 return filter_->Includes(entry_.pid, entry_.ppid); |
| 203 } | 202 } |
| 204 | 203 |
| 205 int GetProcessCount(const std::wstring& executable_name, | |
| 206 const ProcessFilter* filter) { | |
| 207 int count = 0; | |
| 208 | |
| 209 NamedProcessIterator iter(executable_name, filter); | |
| 210 while (iter.NextProcessEntry()) | |
| 211 ++count; | |
| 212 return count; | |
| 213 } | |
| 214 | |
| 215 bool KillProcesses(const std::wstring& executable_name, int exit_code, | |
| 216 const ProcessFilter* filter) { | |
| 217 bool result = true; | |
| 218 const ProcessEntry* entry; | |
| 219 | |
| 220 NamedProcessIterator iter(executable_name, filter); | |
| 221 while ((entry = iter.NextProcessEntry()) != NULL) | |
| 222 result = KillProcess((*entry).pid, exit_code, true) && result; | |
| 223 | |
| 224 return result; | |
| 225 } | |
| 226 | |
| 227 bool WaitForProcessesToExit(const std::wstring& executable_name, | |
| 228 int wait_milliseconds, | |
| 229 const ProcessFilter* filter) { | |
| 230 bool result = false; | |
| 231 | |
| 232 // TODO(port): This is inefficient, but works if there are multiple procs. | |
| 233 // TODO(port): use waitpid to avoid leaving zombies around | |
| 234 | |
| 235 base::Time end_time = base::Time::Now() + | |
| 236 base::TimeDelta::FromMilliseconds(wait_milliseconds); | |
| 237 do { | |
| 238 NamedProcessIterator iter(executable_name, filter); | |
| 239 if (!iter.NextProcessEntry()) { | |
| 240 result = true; | |
| 241 break; | |
| 242 } | |
| 243 PlatformThread::Sleep(100); | |
| 244 } while ((base::Time::Now() - end_time) > base::TimeDelta()); | |
| 245 | |
| 246 return result; | |
| 247 } | |
| 248 | |
| 249 bool CleanupProcesses(const std::wstring& executable_name, | |
| 250 int wait_milliseconds, | |
| 251 int exit_code, | |
| 252 const ProcessFilter* filter) { | |
| 253 bool exited_cleanly = | |
| 254 WaitForProcessesToExit(executable_name, wait_milliseconds, | |
| 255 filter); | |
| 256 if (!exited_cleanly) | |
| 257 KillProcesses(executable_name, exit_code, filter); | |
| 258 return exited_cleanly; | |
| 259 } | |
| 260 | |
| 261 // To have /proc/self/io file you must enable CONFIG_TASK_IO_ACCOUNTING | 204 // To have /proc/self/io file you must enable CONFIG_TASK_IO_ACCOUNTING |
| 262 // in your kernel configuration. | 205 // in your kernel configuration. |
| 263 bool ProcessMetrics::GetIOCounters(IoCounters* io_counters) { | 206 bool ProcessMetrics::GetIOCounters(IoCounters* io_counters) { |
| 264 std::string proc_io_contents; | 207 std::string proc_io_contents; |
| 265 if (!file_util::ReadFileToString(L"/proc/self/io", &proc_io_contents)) | 208 if (!file_util::ReadFileToString(L"/proc/self/io", &proc_io_contents)) |
| 266 return false; | 209 return false; |
| 267 | 210 |
| 268 (*io_counters).OtherOperationCount = 0; | 211 (*io_counters).OtherOperationCount = 0; |
| 269 (*io_counters).OtherTransferCount = 0; | 212 (*io_counters).OtherTransferCount = 0; |
| 270 | 213 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 289 (*io_counters).WriteTransferCount = StringToInt64(tokenizer.token()); | 232 (*io_counters).WriteTransferCount = StringToInt64(tokenizer.token()); |
| 290 } | 233 } |
| 291 state = KEY_NAME; | 234 state = KEY_NAME; |
| 292 break; | 235 break; |
| 293 } | 236 } |
| 294 } | 237 } |
| 295 return true; | 238 return true; |
| 296 } | 239 } |
| 297 | 240 |
| 298 } // namespace base | 241 } // namespace base |
| OLD | NEW |