OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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_impl.h" | 5 #include "content/browser/browser_child_process_host_impl.h" |
6 | 6 |
7 #include "base/base_switches.h" | 7 #include "base/base_switches.h" |
8 #include "base/bind.h" | 8 #include "base/bind.h" |
9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
10 #include "base/files/file_path.h" | 10 #include "base/files/file_path.h" |
11 #include "base/lazy_instance.h" | 11 #include "base/lazy_instance.h" |
12 #include "base/logging.h" | 12 #include "base/logging.h" |
13 #include "base/metrics/histogram.h" | 13 #include "base/metrics/histogram.h" |
14 #include "base/path_service.h" | 14 #include "base/path_service.h" |
15 #include "base/process_util.h" | 15 #include "base/process_util.h" |
16 #include "base/stl_util.h" | 16 #include "base/stl_util.h" |
17 #include "base/string_util.h" | 17 #include "base/string_util.h" |
| 18 #include "base/synchronization/waitable_event.h" |
18 #include "content/browser/histogram_message_filter.h" | 19 #include "content/browser/histogram_message_filter.h" |
19 #include "content/browser/loader/resource_message_filter.h" | 20 #include "content/browser/loader/resource_message_filter.h" |
20 #include "content/browser/profiler_message_filter.h" | 21 #include "content/browser/profiler_message_filter.h" |
21 #include "content/browser/tracing/trace_message_filter.h" | 22 #include "content/browser/tracing/trace_message_filter.h" |
22 #include "content/common/child_process_host_impl.h" | 23 #include "content/common/child_process_host_impl.h" |
23 #include "content/common/plugin_messages.h" | 24 #include "content/common/plugin_messages.h" |
24 #include "content/public/browser/browser_child_process_host_delegate.h" | 25 #include "content/public/browser/browser_child_process_host_delegate.h" |
25 #include "content/public/browser/browser_child_process_observer.h" | 26 #include "content/public/browser/browser_child_process_observer.h" |
26 #include "content/public/browser/browser_thread.h" | 27 #include "content/public/browser/browser_thread.h" |
27 #include "content/public/browser/child_process_data.h" | 28 #include "content/public/browser/child_process_data.h" |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
102 child_process_host_->AddFilter(new TraceMessageFilter); | 103 child_process_host_->AddFilter(new TraceMessageFilter); |
103 child_process_host_->AddFilter(new ProfilerMessageFilter(type)); | 104 child_process_host_->AddFilter(new ProfilerMessageFilter(type)); |
104 child_process_host_->AddFilter(new HistogramMessageFilter()); | 105 child_process_host_->AddFilter(new HistogramMessageFilter()); |
105 | 106 |
106 g_child_process_list.Get().push_back(this); | 107 g_child_process_list.Get().push_back(this); |
107 GetContentClient()->browser()->BrowserChildProcessHostCreated(this); | 108 GetContentClient()->browser()->BrowserChildProcessHostCreated(this); |
108 } | 109 } |
109 | 110 |
110 BrowserChildProcessHostImpl::~BrowserChildProcessHostImpl() { | 111 BrowserChildProcessHostImpl::~BrowserChildProcessHostImpl() { |
111 g_child_process_list.Get().remove(this); | 112 g_child_process_list.Get().remove(this); |
| 113 |
| 114 #if defined(OS_WIN) |
| 115 DeleteProcessWaitableEvent(early_exit_watcher_.GetWatchedEvent()); |
| 116 #endif |
112 } | 117 } |
113 | 118 |
114 // static | 119 // static |
115 void BrowserChildProcessHostImpl::TerminateAll() { | 120 void BrowserChildProcessHostImpl::TerminateAll() { |
116 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 121 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
117 // Make a copy since the BrowserChildProcessHost dtor mutates the original | 122 // Make a copy since the BrowserChildProcessHost dtor mutates the original |
118 // list. | 123 // list. |
119 BrowserChildProcessList copy = g_child_process_list.Get(); | 124 BrowserChildProcessList copy = g_child_process_list.Get(); |
120 for (BrowserChildProcessList::iterator it = copy.begin(); | 125 for (BrowserChildProcessList::iterator it = copy.begin(); |
121 it != copy.end(); ++it) { | 126 it != copy.end(); ++it) { |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
220 return child_process_->GetChildTerminationStatus(false /* known_dead */, | 225 return child_process_->GetChildTerminationStatus(false /* known_dead */, |
221 exit_code); | 226 exit_code); |
222 } | 227 } |
223 | 228 |
224 bool BrowserChildProcessHostImpl::OnMessageReceived( | 229 bool BrowserChildProcessHostImpl::OnMessageReceived( |
225 const IPC::Message& message) { | 230 const IPC::Message& message) { |
226 return delegate_->OnMessageReceived(message); | 231 return delegate_->OnMessageReceived(message); |
227 } | 232 } |
228 | 233 |
229 void BrowserChildProcessHostImpl::OnChannelConnected(int32 peer_pid) { | 234 void BrowserChildProcessHostImpl::OnChannelConnected(int32 peer_pid) { |
| 235 #if defined(OS_WIN) |
| 236 // From this point onward, the exit of the child process is detected by an |
| 237 // error on the IPC channel. |
| 238 DeleteProcessWaitableEvent(early_exit_watcher_.GetWatchedEvent()); |
| 239 early_exit_watcher_.StopWatching(); |
| 240 #endif |
| 241 |
230 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 242 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
231 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 243 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
232 base::Bind(&NotifyProcessHostConnected, data_)); | 244 base::Bind(&NotifyProcessHostConnected, data_)); |
| 245 |
233 delegate_->OnChannelConnected(peer_pid); | 246 delegate_->OnChannelConnected(peer_pid); |
234 } | 247 } |
235 | 248 |
236 void BrowserChildProcessHostImpl::OnChannelError() { | 249 void BrowserChildProcessHostImpl::OnChannelError() { |
237 delegate_->OnChannelError(); | 250 delegate_->OnChannelError(); |
238 } | 251 } |
239 | 252 |
240 bool BrowserChildProcessHostImpl::CanShutdown() { | 253 bool BrowserChildProcessHostImpl::CanShutdown() { |
241 return delegate_->CanShutdown(); | 254 return delegate_->CanShutdown(); |
242 } | 255 } |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
283 | 296 |
284 bool BrowserChildProcessHostImpl::Send(IPC::Message* message) { | 297 bool BrowserChildProcessHostImpl::Send(IPC::Message* message) { |
285 return child_process_host_->Send(message); | 298 return child_process_host_->Send(message); |
286 } | 299 } |
287 | 300 |
288 void BrowserChildProcessHostImpl::OnProcessLaunched() { | 301 void BrowserChildProcessHostImpl::OnProcessLaunched() { |
289 if (!child_process_->GetHandle()) { | 302 if (!child_process_->GetHandle()) { |
290 delete delegate_; // Will delete us | 303 delete delegate_; // Will delete us |
291 return; | 304 return; |
292 } | 305 } |
| 306 |
| 307 #if defined(OS_WIN) |
| 308 // Start a WaitableEventWatcher that will invoke OnProcessExitedEarly if the |
| 309 // child process exits. This watcher is stopped once the IPC channel is |
| 310 // connected and the exit of the child process is detecter by an error on the |
| 311 // IPC channel thereafter. |
| 312 DCHECK(!early_exit_watcher_.GetWatchedEvent()); |
| 313 early_exit_watcher_.StartWatching( |
| 314 new base::WaitableEvent(child_process_->GetHandle()), |
| 315 base::Bind(&BrowserChildProcessHostImpl::OnProcessExitedEarly, |
| 316 base::Unretained(this))); |
| 317 #endif |
| 318 |
293 data_.handle = child_process_->GetHandle(); | 319 data_.handle = child_process_->GetHandle(); |
294 delegate_->OnProcessLaunched(); | 320 delegate_->OnProcessLaunched(); |
295 } | 321 } |
296 | 322 |
| 323 #if defined(OS_WIN) |
| 324 |
| 325 void BrowserChildProcessHostImpl::DeleteProcessWaitableEvent( |
| 326 base::WaitableEvent* event) { |
| 327 if (!event) |
| 328 return; |
| 329 |
| 330 // The WaitableEvent does not own the process handle so ensure it does not |
| 331 // close it. |
| 332 event->Release(); |
| 333 |
| 334 delete event; |
| 335 } |
| 336 |
| 337 void BrowserChildProcessHostImpl::OnProcessExitedEarly( |
| 338 base::WaitableEvent* event) { |
| 339 DeleteProcessWaitableEvent(event); |
| 340 OnChildDisconnected(); |
| 341 } |
| 342 |
| 343 #endif |
| 344 |
297 } // namespace content | 345 } // namespace content |
OLD | NEW |