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

Side by Side Diff: content/browser/browser_child_process_host.cc

Issue 8774040: Don't make classes derive from ChildProcessHost, and instead have them use it through composition... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 "content/browser/browser_child_process_host.h" 5 #include "content/browser/browser_child_process_host.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/command_line.h" 8 #include "base/command_line.h"
9 #include "base/file_path.h" 9 #include "base/file_path.h"
10 #include "base/lazy_instance.h" 10 #include "base/lazy_instance.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/metrics/histogram.h" 12 #include "base/metrics/histogram.h"
13 #include "base/path_service.h" 13 #include "base/path_service.h"
14 #include "base/process_util.h" 14 #include "base/process_util.h"
15 #include "base/stl_util.h" 15 #include "base/stl_util.h"
16 #include "base/string_util.h" 16 #include "base/string_util.h"
17 #include "content/browser/profiler_message_filter.h" 17 #include "content/browser/profiler_message_filter.h"
18 #include "content/browser/renderer_host/resource_message_filter.h" 18 #include "content/browser/renderer_host/resource_message_filter.h"
19 #include "content/browser/trace_message_filter.h" 19 #include "content/browser/trace_message_filter.h"
20 #include "content/common/child_process_host.h"
20 #include "content/common/plugin_messages.h" 21 #include "content/common/plugin_messages.h"
21 #include "content/public/browser/browser_thread.h" 22 #include "content/public/browser/browser_thread.h"
22 #include "content/public/browser/child_process_data.h" 23 #include "content/public/browser/child_process_data.h"
23 #include "content/public/browser/content_browser_client.h" 24 #include "content/public/browser/content_browser_client.h"
24 #include "content/public/browser/notification_service.h" 25 #include "content/public/browser/notification_service.h"
25 #include "content/public/browser/notification_types.h" 26 #include "content/public/browser/notification_types.h"
26 #include "content/public/common/content_switches.h" 27 #include "content/public/common/content_switches.h"
27 #include "content/public/common/result_codes.h" 28 #include "content/public/common/result_codes.h"
28 29
29 #if defined(OS_WIN) 30 #if defined(OS_WIN)
(...skipping 22 matching lines...) Expand all
52 } // namespace 53 } // namespace
53 54
54 BrowserChildProcessHost::BrowserChildProcessHost( 55 BrowserChildProcessHost::BrowserChildProcessHost(
55 content::ProcessType type) 56 content::ProcessType type)
56 : ALLOW_THIS_IN_INITIALIZER_LIST(client_(this)), 57 : ALLOW_THIS_IN_INITIALIZER_LIST(client_(this)),
57 #if !defined(OS_WIN) 58 #if !defined(OS_WIN)
58 ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)), 59 ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)),
59 #endif 60 #endif
60 disconnect_was_alive_(false) { 61 disconnect_was_alive_(false) {
61 data_.type = type; 62 data_.type = type;
62 data_.id = GenerateChildProcessUniqueId(); 63 data_.id = ChildProcessHost::GenerateChildProcessUniqueId();
63 64
64 AddFilter(new TraceMessageFilter); 65 child_process_host_.reset(new ChildProcessHost(this));
65 AddFilter(new ProfilerMessageFilter); 66 child_process_host_->AddFilter(new TraceMessageFilter);
67 child_process_host_->AddFilter(new ProfilerMessageFilter);
66 68
67 g_child_process_list.Get().push_back(this); 69 g_child_process_list.Get().push_back(this);
68 } 70 }
69 71
70 BrowserChildProcessHost::~BrowserChildProcessHost() { 72 BrowserChildProcessHost::~BrowserChildProcessHost() {
71 g_child_process_list.Get().remove(this); 73 g_child_process_list.Get().remove(this);
72 } 74 }
73 75
74 // static 76 // static
75 void BrowserChildProcessHost::TerminateAll() { 77 void BrowserChildProcessHost::TerminateAll() {
(...skipping 13 matching lines...) Expand all
89 91
90 content::GetContentClient()->browser()->AppendExtraCommandLineSwitches( 92 content::GetContentClient()->browser()->AppendExtraCommandLineSwitches(
91 cmd_line, id()); 93 cmd_line, id());
92 94
93 child_process_.reset(new ChildProcessLauncher( 95 child_process_.reset(new ChildProcessLauncher(
94 #if defined(OS_WIN) 96 #if defined(OS_WIN)
95 exposed_dir, 97 exposed_dir,
96 #elif defined(OS_POSIX) 98 #elif defined(OS_POSIX)
97 use_zygote, 99 use_zygote,
98 environ, 100 environ,
99 channel()->TakeClientFileDescriptor(), 101 child_process_host()->channel()->TakeClientFileDescriptor(),
100 #endif 102 #endif
101 cmd_line, 103 cmd_line,
102 &client_)); 104 &client_));
103 } 105 }
104 106
105 base::ProcessHandle BrowserChildProcessHost::GetChildProcessHandle() const { 107 base::ProcessHandle BrowserChildProcessHost::GetChildProcessHandle() const {
106 DCHECK(child_process_.get()) 108 DCHECK(child_process_.get())
107 << "Requesting a child process handle before launching."; 109 << "Requesting a child process handle before launching.";
108 DCHECK(child_process_->GetHandle()) 110 DCHECK(child_process_->GetHandle())
109 << "Requesting a child process handle before launch has completed OK."; 111 << "Requesting a child process handle before launch has completed OK.";
110 return child_process_->GetHandle(); 112 return child_process_->GetHandle();
111 } 113 }
112 114
113 void BrowserChildProcessHost::ForceShutdown() { 115 void BrowserChildProcessHost::ForceShutdown() {
114 g_child_process_list.Get().remove(this); 116 g_child_process_list.Get().remove(this);
115 ChildProcessHost::ForceShutdown(); 117 child_process_host_->ForceShutdown();
116 } 118 }
117 119
118 void BrowserChildProcessHost::SetTerminateChildOnShutdown( 120 void BrowserChildProcessHost::SetTerminateChildOnShutdown(
119 bool terminate_on_shutdown) { 121 bool terminate_on_shutdown) {
120 child_process_->SetTerminateChildOnShutdown(terminate_on_shutdown); 122 child_process_->SetTerminateChildOnShutdown(terminate_on_shutdown);
121 } 123 }
122 124
123 void BrowserChildProcessHost::Notify(int type) { 125 void BrowserChildProcessHost::Notify(int type) {
124 BrowserThread::PostTask( 126 BrowserThread::PostTask(
125 BrowserThread::UI, 127 BrowserThread::UI,
126 FROM_HERE, 128 FROM_HERE,
127 base::Bind(&ChildNotificationHelper, type, data_)); 129 base::Bind(&ChildNotificationHelper, type, data_));
128 } 130 }
129 131
130 base::TerminationStatus BrowserChildProcessHost::GetChildTerminationStatus( 132 base::TerminationStatus BrowserChildProcessHost::GetChildTerminationStatus(
131 int* exit_code) { 133 int* exit_code) {
132 return child_process_->GetChildTerminationStatus(exit_code); 134 return child_process_->GetChildTerminationStatus(exit_code);
133 } 135 }
134 136
137 bool BrowserChildProcessHost::OnMessageReceived(const IPC::Message& message) {
138 return false;
139 }
140
141
135 void BrowserChildProcessHost::OnChannelConnected(int32 peer_pid) { 142 void BrowserChildProcessHost::OnChannelConnected(int32 peer_pid) {
136 Notify(content::NOTIFICATION_CHILD_PROCESS_HOST_CONNECTED); 143 Notify(content::NOTIFICATION_CHILD_PROCESS_HOST_CONNECTED);
137 } 144 }
138 145
139 // The ChildProcessHost default implementation calls OnChildDied() always but at 146 bool BrowserChildProcessHost::CanShutdown() {
147 return true;
148 }
149
150 // Normally a ChildProcessHostDelegate deletes itself from this callback, but at
140 // this layer and below we need to have the final child process exit code to 151 // this layer and below we need to have the final child process exit code to
141 // properly bucket crashes vs kills. On Windows we can do this if we wait until 152 // properly bucket crashes vs kills. On Windows we can do this if we wait until
142 // the process handle is signaled; on the rest of the platforms, we schedule a 153 // the process handle is signaled; on the rest of the platforms, we schedule a
143 // delayed task to wait for an exit code. However, this means that this method 154 // delayed task to wait for an exit code. However, this means that this method
144 // may be called twice: once from the actual channel error and once from 155 // may be called twice: once from the actual channel error and once from
145 // OnWaitableEventSignaled() or the delayed task. 156 // OnWaitableEventSignaled() or the delayed task.
146 void BrowserChildProcessHost::OnChildDisconnected() { 157 void BrowserChildProcessHost::OnChildDisconnected() {
147 DCHECK(handle() != base::kNullProcessHandle); 158 DCHECK(handle() != base::kNullProcessHandle);
148 int exit_code; 159 int exit_code;
149 base::TerminationStatus status = GetChildTerminationStatus(&exit_code); 160 base::TerminationStatus status = GetChildTerminationStatus(&exit_code);
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
205 } 216 }
206 217
207 default: 218 default:
208 break; 219 break;
209 } 220 }
210 UMA_HISTOGRAM_ENUMERATION("ChildProcess.Disconnected", 221 UMA_HISTOGRAM_ENUMERATION("ChildProcess.Disconnected",
211 this->type(), 222 this->type(),
212 content::PROCESS_TYPE_MAX); 223 content::PROCESS_TYPE_MAX);
213 // Notify in the main loop of the disconnection. 224 // Notify in the main loop of the disconnection.
214 Notify(content::NOTIFICATION_CHILD_PROCESS_HOST_DISCONNECTED); 225 Notify(content::NOTIFICATION_CHILD_PROCESS_HOST_DISCONNECTED);
215 OnChildDied(); 226 delete this;
216 } 227 }
217 228
218 // The child process handle has been signaled so the exit code is finally 229 // The child process handle has been signaled so the exit code is finally
219 // available. Unfortunately STILL_ACTIVE (0x103) is a valid exit code in 230 // available. Unfortunately STILL_ACTIVE (0x103) is a valid exit code in
220 // which case we should not call OnChildDisconnected() or else we will be 231 // which case we should not call OnChildDisconnected() or else we will be
221 // waiting forever. 232 // waiting forever.
222 void BrowserChildProcessHost::OnWaitableEventSignaled( 233 void BrowserChildProcessHost::OnWaitableEventSignaled(
223 base::WaitableEvent* waitable_event) { 234 base::WaitableEvent* waitable_event) {
224 #if defined (OS_WIN) 235 #if defined (OS_WIN)
225 unsigned long exit_code = 0; 236 unsigned long exit_code = 0;
226 GetExitCodeProcess(waitable_event->Release(), &exit_code); 237 GetExitCodeProcess(waitable_event->Release(), &exit_code);
227 delete waitable_event; 238 delete waitable_event;
228 if (exit_code == STILL_ACTIVE) 239 if (exit_code == STILL_ACTIVE) {
229 OnChildDied(); 240 delete this;
230 BrowserChildProcessHost::OnChildDisconnected(); 241 } else {
242 BrowserChildProcessHost::OnChildDisconnected();
243 }
231 #endif 244 #endif
232 } 245 }
233 246
247 bool BrowserChildProcessHost::Send(IPC::Message* message) {
248 return child_process_host_->Send(message);
249 }
250
234 void BrowserChildProcessHost::ShutdownStarted() { 251 void BrowserChildProcessHost::ShutdownStarted() {
235 // Must remove the process from the list now, in case it gets used for a 252 // Must remove the process from the list now, in case it gets used for a
236 // new instance before our watcher tells us that the process terminated. 253 // new instance before our watcher tells us that the process terminated.
237 g_child_process_list.Get().remove(this); 254 g_child_process_list.Get().remove(this);
238 } 255 }
239 256
240 BrowserChildProcessHost::ClientHook::ClientHook(BrowserChildProcessHost* host) 257 BrowserChildProcessHost::ClientHook::ClientHook(BrowserChildProcessHost* host)
241 : host_(host) { 258 : host_(host) {
242 } 259 }
243 260
244 void BrowserChildProcessHost::ClientHook::OnProcessLaunched() { 261 void BrowserChildProcessHost::ClientHook::OnProcessLaunched() {
245 if (!host_->child_process_->GetHandle()) { 262 if (!host_->child_process_->GetHandle()) {
246 host_->OnChildDied(); 263 delete host_;
247 return; 264 return;
248 } 265 }
249 host_->data_.handle = host_->child_process_->GetHandle(); 266 host_->data_.handle = host_->child_process_->GetHandle();
250 host_->OnProcessLaunched(); 267 host_->OnProcessLaunched();
251 } 268 }
252 269
253 BrowserChildProcessHost::Iterator::Iterator() 270 BrowserChildProcessHost::Iterator::Iterator()
254 : all_(true), type_(content::PROCESS_TYPE_UNKNOWN) { 271 : all_(true), type_(content::PROCESS_TYPE_UNKNOWN) {
255 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)) << 272 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)) <<
256 "BrowserChildProcessHost::Iterator must be used on the IO thread."; 273 "BrowserChildProcessHost::Iterator must be used on the IO thread.";
(...skipping 20 matching lines...) Expand all
277 294
278 return *iterator_; 295 return *iterator_;
279 } while (true); 296 } while (true);
280 297
281 return NULL; 298 return NULL;
282 } 299 }
283 300
284 bool BrowserChildProcessHost::Iterator::Done() { 301 bool BrowserChildProcessHost::Iterator::Done() {
285 return iterator_ == g_child_process_list.Get().end(); 302 return iterator_ == g_child_process_list.Get().end();
286 } 303 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698