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

Side by Side Diff: chrome/common/process_watcher.cc

Issue 18446: Porting in chrome/ (Closed)
Patch Set: last fixes Created 11 years, 11 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
« no previous file with comments | « chrome/common/common.scons ('k') | chrome/common/security_filter_peer.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-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 "chrome/common/process_watcher.h" 5 #include "chrome/common/process_watcher.h"
6 6
7 #include "base/basictypes.h"
7 #include "base/message_loop.h" 8 #include "base/message_loop.h"
8 #include "base/object_watcher.h" 9 #include "base/process.h"
10 #include "base/process_util.h"
9 #include "base/sys_info.h" 11 #include "base/sys_info.h"
12 #include "base/timer.h"
13 #include "base/worker_pool.h"
10 #include "chrome/app/result_codes.h" 14 #include "chrome/app/result_codes.h"
11 #include "chrome/common/env_vars.h" 15 #include "chrome/common/env_vars.h"
12 16
13 // Maximum amount of time (in milliseconds) to wait for the process to exit. 17 // Maximum amount of time (in milliseconds) to wait for the process to exit.
14 static const int kWaitInterval = 2000; 18 static const int kWaitInterval = 2000;
15 19
16 namespace { 20 namespace {
17 21
18 class TimerExpiredTask : public Task, public base::ObjectWatcher::Delegate { 22 class TerminatorTask : public Task {
19 public: 23 public:
20 explicit TimerExpiredTask(base::ProcessHandle process) : process_(process) { 24 explicit TerminatorTask(base::ProcessHandle process) : process_(process) {
21 watcher_.StartWatching(process_, this); 25 timer_.Start(base::TimeDelta::FromMilliseconds(kWaitInterval),
26 this, &TerminatorTask::KillProcess);
22 } 27 }
23 28
24 virtual ~TimerExpiredTask() { 29 virtual ~TerminatorTask() {
25 if (process_) { 30 if (process_) {
26 KillProcess(); 31 KillProcess();
27 DCHECK(!process_) << "Make sure to close the handle."; 32 DCHECK(!process_);
28 } 33 }
29 } 34 }
30 35
31 // Task ---------------------------------------------------------------------
32
33 virtual void Run() { 36 virtual void Run() {
37 base::WaitForSingleProcess(process_, kWaitInterval);
38 timer_.Stop();
34 if (process_) 39 if (process_)
35 KillProcess(); 40 KillProcess();
36 } 41 }
37 42
38 // MessageLoop::Watcher -----------------------------------------------------
39
40 virtual void OnObjectSignaled(HANDLE object) {
41 // When we're called from KillProcess, the ObjectWatcher may still be
42 // watching. the process handle, so make sure it has stopped.
43 watcher_.StopWatching();
44
45 CloseHandle(process_);
46 process_ = NULL;
47 }
48
49 private: 43 private:
50 void KillProcess() { 44 void KillProcess() {
51 if (base::SysInfo::HasEnvVar(env_vars::kHeadless)) { 45 if (base::SysInfo::HasEnvVar(env_vars::kHeadless)) {
52 // If running the distributed tests, give the renderer a little time 46 // If running the distributed tests, give the renderer a little time
53 // to figure out that the channel is shutdown and unwind. 47 // to figure out that the channel is shutdown and unwind.
54 if (WaitForSingleObject(process_, kWaitInterval) == WAIT_OBJECT_0) { 48 if (base::WaitForSingleProcess(process_, kWaitInterval)) {
55 OnObjectSignaled(process_); 49 Cleanup();
56 return; 50 return;
57 } 51 }
58 } 52 }
59 53
60 // OK, time to get frisky. We don't actually care when the process 54 // OK, time to get frisky. We don't actually care when the process
61 // terminates. We just care that it eventually terminates, and that's what 55 // terminates. We just care that it eventually terminates.
62 // TerminateProcess should do for us. Don't check for the result code since 56 base::KillProcess(base::Process(process_).pid(),
63 // it fails quite often. This should be investigated eventually. 57 ResultCodes::HUNG,
64 TerminateProcess(process_, ResultCodes::HUNG); 58 false /* don't wait */);
65 59
66 // Now, just cleanup as if the process exited normally. 60 Cleanup();
67 OnObjectSignaled(process_); 61 }
62
63 void Cleanup() {
64 timer_.Stop();
65 base::CloseProcessHandle(process_);
66 process_ = NULL;
68 } 67 }
69 68
70 // The process that we are watching. 69 // The process that we are watching.
71 base::ProcessHandle process_; 70 base::ProcessHandle process_;
72 71
73 base::ObjectWatcher watcher_; 72 base::OneShotTimer<TerminatorTask> timer_;
74 73
75 DISALLOW_EVIL_CONSTRUCTORS(TimerExpiredTask); 74 DISALLOW_COPY_AND_ASSIGN(TerminatorTask);
76 }; 75 };
77 76
78 } // namespace 77 } // namespace
79 78
80 // static 79 // static
81 void ProcessWatcher::EnsureProcessTerminated(base::ProcessHandle process) { 80 void ProcessWatcher::EnsureProcessTerminated(base::ProcessHandle process) {
82 DCHECK(process != GetCurrentProcess()); 81 DCHECK(base::GetProcId(process) != base::GetCurrentProcId());
83 82
84 // If already signaled, then we are done! 83 // Check if the process has already exited.
85 if (WaitForSingleObject(process, 0) == WAIT_OBJECT_0) { 84 if (base::WaitForSingleProcess(process, 0)) {
86 CloseHandle(process); 85 base::CloseProcessHandle(process);
87 return; 86 return;
88 } 87 }
89 88
90 MessageLoop::current()->PostDelayedTask(FROM_HERE, 89 WorkerPool::PostTask(FROM_HERE, new TerminatorTask(process), true);
91 new TimerExpiredTask(process),
92 kWaitInterval);
93 } 90 }
94
OLDNEW
« no previous file with comments | « chrome/common/common.scons ('k') | chrome/common/security_filter_peer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698