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

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

Issue 10702048: Remove the code to wait on disconnected child processes to get the exit code. This was done in r101… (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: sync Created 8 years, 5 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 | Annotate | Revision Log
OLDNEW
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/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"
(...skipping 10 matching lines...) Expand all
21 #include "content/common/plugin_messages.h" 21 #include "content/common/plugin_messages.h"
22 #include "content/public/browser/browser_thread.h" 22 #include "content/public/browser/browser_thread.h"
23 #include "content/public/browser/browser_child_process_host_delegate.h" 23 #include "content/public/browser/browser_child_process_host_delegate.h"
24 #include "content/public/browser/child_process_data.h" 24 #include "content/public/browser/child_process_data.h"
25 #include "content/public/browser/content_browser_client.h" 25 #include "content/public/browser/content_browser_client.h"
26 #include "content/public/browser/notification_service.h" 26 #include "content/public/browser/notification_service.h"
27 #include "content/public/browser/notification_types.h" 27 #include "content/public/browser/notification_types.h"
28 #include "content/public/common/content_switches.h" 28 #include "content/public/common/content_switches.h"
29 #include "content/public/common/result_codes.h" 29 #include "content/public/common/result_codes.h"
30 30
31 #if defined(OS_WIN) 31 #if defined(OS_MACOSX)
32 #include "base/synchronization/waitable_event.h"
33 #elif defined(OS_MACOSX)
34 #include "content/browser/mach_broker_mac.h" 32 #include "content/browser/mach_broker_mac.h"
35 #endif 33 #endif
36 34
37 using content::BrowserChildProcessHostDelegate; 35 using content::BrowserChildProcessHostDelegate;
38 using content::BrowserThread; 36 using content::BrowserThread;
39 using content::ChildProcessData; 37 using content::ChildProcessData;
40 using content::ChildProcessHost; 38 using content::ChildProcessHost;
41 using content::ChildProcessHostImpl; 39 using content::ChildProcessHostImpl;
42 40
43 namespace { 41 namespace {
(...skipping 30 matching lines...) Expand all
74 72
75 BrowserChildProcessHostImpl::BrowserChildProcessList* 73 BrowserChildProcessHostImpl::BrowserChildProcessList*
76 BrowserChildProcessHostImpl::GetIterator() { 74 BrowserChildProcessHostImpl::GetIterator() {
77 return g_child_process_list.Pointer(); 75 return g_child_process_list.Pointer();
78 } 76 }
79 77
80 BrowserChildProcessHostImpl::BrowserChildProcessHostImpl( 78 BrowserChildProcessHostImpl::BrowserChildProcessHostImpl(
81 content::ProcessType type, 79 content::ProcessType type,
82 BrowserChildProcessHostDelegate* delegate) 80 BrowserChildProcessHostDelegate* delegate)
83 : data_(type), 81 : data_(type),
84 delegate_(delegate), 82 delegate_(delegate) {
85 #if !defined(OS_WIN)
86 ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)),
87 #endif
88 disconnect_was_alive_(false) {
89 data_.id = ChildProcessHostImpl::GenerateChildProcessUniqueId(); 83 data_.id = ChildProcessHostImpl::GenerateChildProcessUniqueId();
90 84
91 child_process_host_.reset(ChildProcessHost::Create(this)); 85 child_process_host_.reset(ChildProcessHost::Create(this));
92 child_process_host_->AddFilter(new TraceMessageFilter); 86 child_process_host_->AddFilter(new TraceMessageFilter);
93 child_process_host_->AddFilter(new content::ProfilerMessageFilter(type)); 87 child_process_host_->AddFilter(new content::ProfilerMessageFilter(type));
94 88
95 g_child_process_list.Get().push_back(this); 89 g_child_process_list.Get().push_back(this);
96 content::GetContentClient()->browser()->BrowserChildProcessHostCreated(this); 90 content::GetContentClient()->browser()->BrowserChildProcessHostCreated(this);
97 } 91 }
98 92
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
204 } 198 }
205 199
206 void BrowserChildProcessHostImpl::OnChannelError() { 200 void BrowserChildProcessHostImpl::OnChannelError() {
207 delegate_->OnChannelError(); 201 delegate_->OnChannelError();
208 } 202 }
209 203
210 bool BrowserChildProcessHostImpl::CanShutdown() { 204 bool BrowserChildProcessHostImpl::CanShutdown() {
211 return delegate_->CanShutdown(); 205 return delegate_->CanShutdown();
212 } 206 }
213 207
214 // Normally a ChildProcessHostDelegate deletes itself from this callback, but at
215 // this layer and below we need to have the final child process exit code to
216 // properly bucket crashes vs kills. On Windows we can do this if we wait until
217 // the process handle is signaled; on the rest of the platforms, we schedule a
218 // delayed task to wait for an exit code. However, this means that this method
219 // may be called twice: once from the actual channel error and once from
220 // OnWaitableEventSignaled() or the delayed task.
221 void BrowserChildProcessHostImpl::OnChildDisconnected() { 208 void BrowserChildProcessHostImpl::OnChildDisconnected() {
222 DCHECK(data_.handle != base::kNullProcessHandle); 209 DCHECK(data_.handle != base::kNullProcessHandle);
223 int exit_code; 210 int exit_code;
224 base::TerminationStatus status = GetTerminationStatus(&exit_code); 211 base::TerminationStatus status = GetTerminationStatus(&exit_code);
225 switch (status) { 212 switch (status) {
226 case base::TERMINATION_STATUS_PROCESS_CRASHED: 213 case base::TERMINATION_STATUS_PROCESS_CRASHED:
227 case base::TERMINATION_STATUS_ABNORMAL_TERMINATION: { 214 case base::TERMINATION_STATUS_ABNORMAL_TERMINATION: {
228 delegate_->OnProcessCrashed(exit_code); 215 delegate_->OnProcessCrashed(exit_code);
229 // Report that this child process crashed. 216 // Report that this child process crashed.
230 Notify(content::NOTIFICATION_CHILD_PROCESS_CRASHED); 217 Notify(content::NOTIFICATION_CHILD_PROCESS_CRASHED);
231 UMA_HISTOGRAM_ENUMERATION("ChildProcess.Crashed", 218 UMA_HISTOGRAM_ENUMERATION("ChildProcess.Crashed",
232 data_.type, 219 data_.type,
233 content::PROCESS_TYPE_MAX); 220 content::PROCESS_TYPE_MAX);
234 if (disconnect_was_alive_) {
235 UMA_HISTOGRAM_ENUMERATION("ChildProcess.CrashedWasAlive",
236 data_.type,
237 content::PROCESS_TYPE_MAX);
238 }
239 break; 221 break;
240 } 222 }
241 case base::TERMINATION_STATUS_PROCESS_WAS_KILLED: { 223 case base::TERMINATION_STATUS_PROCESS_WAS_KILLED: {
242 delegate_->OnProcessCrashed(exit_code); 224 delegate_->OnProcessCrashed(exit_code);
243 // Report that this child process was killed. 225 // Report that this child process was killed.
244 UMA_HISTOGRAM_ENUMERATION("ChildProcess.Killed", 226 UMA_HISTOGRAM_ENUMERATION("ChildProcess.Killed",
245 data_.type, 227 data_.type,
246 content::PROCESS_TYPE_MAX); 228 content::PROCESS_TYPE_MAX);
247 if (disconnect_was_alive_) {
248 UMA_HISTOGRAM_ENUMERATION("ChildProcess.KilledWasAlive",
249 data_.type,
250 content::PROCESS_TYPE_MAX);
251 }
252 break; 229 break;
253 } 230 }
254 case base::TERMINATION_STATUS_STILL_RUNNING: { 231 case base::TERMINATION_STATUS_STILL_RUNNING: {
255 // Exit code not yet available. Ensure we don't wait forever for an exit 232 UMA_HISTOGRAM_ENUMERATION("ChildProcess.DisconnectedAlive",
256 // code. 233 data_.type,
257 if (disconnect_was_alive_) { 234 content::PROCESS_TYPE_MAX);
258 UMA_HISTOGRAM_ENUMERATION("ChildProcess.DisconnectedAlive",
259 data_.type,
260 content::PROCESS_TYPE_MAX);
261 break;
262 }
263 disconnect_was_alive_ = true;
264 #if defined(OS_WIN)
265 child_watcher_.StartWatching(
266 new base::WaitableEvent(data_.handle), this);
267 #else
268 // On non-Windows platforms, give the child process some time to die after
269 // disconnecting the channel so that the exit code and termination status
270 // become available. This is best effort -- if the process doesn't die
271 // within the time limit, this object gets destroyed.
272 const base::TimeDelta kExitCodeWait =
273 base::TimeDelta::FromMilliseconds(250);
274 MessageLoop::current()->PostDelayedTask(
275 FROM_HERE,
276 base::Bind(&BrowserChildProcessHostImpl::OnChildDisconnected,
277 task_factory_.GetWeakPtr()),
278 kExitCodeWait);
279 #endif
280 return;
281 } 235 }
282
283 default: 236 default:
284 break; 237 break;
285 } 238 }
286 UMA_HISTOGRAM_ENUMERATION("ChildProcess.Disconnected", 239 UMA_HISTOGRAM_ENUMERATION("ChildProcess.Disconnected",
287 data_.type, 240 data_.type,
288 content::PROCESS_TYPE_MAX); 241 content::PROCESS_TYPE_MAX);
289 // Notify in the main loop of the disconnection. 242 // Notify in the main loop of the disconnection.
290 Notify(content::NOTIFICATION_CHILD_PROCESS_HOST_DISCONNECTED); 243 Notify(content::NOTIFICATION_CHILD_PROCESS_HOST_DISCONNECTED);
291 delete delegate_; // Will delete us 244 delete delegate_; // Will delete us
292 } 245 }
293 246
294 // The child process handle has been signaled so the exit code is finally
295 // available. Unfortunately STILL_ACTIVE (0x103) is a valid exit code in
296 // which case we should not call OnChildDisconnected() or else we will be
297 // waiting forever.
298 void BrowserChildProcessHostImpl::OnWaitableEventSignaled(
299 base::WaitableEvent* waitable_event) {
300 #if defined (OS_WIN)
301 unsigned long exit_code = 0;
302 GetExitCodeProcess(waitable_event->Release(), &exit_code);
303 delete waitable_event;
304 if (exit_code == STILL_ACTIVE) {
305 delete delegate_; // Will delete us
306 } else {
307 BrowserChildProcessHostImpl::OnChildDisconnected();
308 }
309 #endif
310 }
311
312 bool BrowserChildProcessHostImpl::Send(IPC::Message* message) { 247 bool BrowserChildProcessHostImpl::Send(IPC::Message* message) {
313 return child_process_host_->Send(message); 248 return child_process_host_->Send(message);
314 } 249 }
315 250
316 void BrowserChildProcessHostImpl::OnProcessLaunched() { 251 void BrowserChildProcessHostImpl::OnProcessLaunched() {
317 if (!child_process_->GetHandle()) { 252 if (!child_process_->GetHandle()) {
318 delete delegate_; // Will delete us 253 delete delegate_; // Will delete us
319 return; 254 return;
320 } 255 }
321 data_.handle = child_process_->GetHandle(); 256 data_.handle = child_process_->GetHandle();
322 delegate_->OnProcessLaunched(); 257 delegate_->OnProcessLaunched();
323 } 258 }
OLDNEW
« no previous file with comments | « content/browser/browser_child_process_host_impl.h ('k') | content/browser/download/download_manager_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698