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

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

Issue 9117006: Rename BrowserChildProcessHost implementation class to BrowserChildProcessHostImpl. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 8 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 | 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_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"
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"
(...skipping 19 matching lines...) Expand all
35 #endif 35 #endif
36 36
37 using content::BrowserChildProcessHostDelegate; 37 using content::BrowserChildProcessHostDelegate;
38 using content::BrowserThread; 38 using content::BrowserThread;
39 using content::ChildProcessData; 39 using content::ChildProcessData;
40 using content::ChildProcessHost; 40 using content::ChildProcessHost;
41 using content::ChildProcessHostImpl; 41 using content::ChildProcessHostImpl;
42 42
43 namespace { 43 namespace {
44 44
45 static base::LazyInstance<BrowserChildProcessHost::BrowserChildProcessList> 45 static base::LazyInstance<BrowserChildProcessHostImpl::BrowserChildProcessList>
46 g_child_process_list = LAZY_INSTANCE_INITIALIZER; 46 g_child_process_list = LAZY_INSTANCE_INITIALIZER;
47 47
48 // Helper functions since the child process related notifications happen on the 48 // Helper functions since the child process related notifications happen on the
49 // UI thread. 49 // UI thread.
50 void ChildNotificationHelper(int notification_type, 50 void ChildNotificationHelper(int notification_type,
51 const ChildProcessData& data) { 51 const ChildProcessData& data) {
52 content::NotificationService::current()-> 52 content::NotificationService::current()->
53 Notify(notification_type, content::NotificationService::AllSources(), 53 Notify(notification_type, content::NotificationService::AllSources(),
54 content::Details<const ChildProcessData>(&data)); 54 content::Details<const ChildProcessData>(&data));
55 } 55 }
56 56
57 } // namespace 57 } // namespace
58 58
59 namespace content { 59 namespace content {
60 60
61 BrowserChildProcessHost* BrowserChildProcessHost::Create( 61 BrowserChildProcessHost* BrowserChildProcessHost::Create(
62 ProcessType type, 62 ProcessType type,
63 BrowserChildProcessHostDelegate* delegate) { 63 BrowserChildProcessHostDelegate* delegate) {
64 return new ::BrowserChildProcessHost(type, delegate); 64 return new BrowserChildProcessHostImpl(type, delegate);
65 } 65 }
66 66
67 } // namespace content 67 } // namespace content
68 68
69 BrowserChildProcessHost::BrowserChildProcessList* 69 BrowserChildProcessHostImpl::BrowserChildProcessList*
70 BrowserChildProcessHost::GetIterator() { 70 BrowserChildProcessHostImpl::GetIterator() {
71 return g_child_process_list.Pointer(); 71 return g_child_process_list.Pointer();
72 } 72 }
73 73
74 BrowserChildProcessHost::BrowserChildProcessHost( 74 BrowserChildProcessHostImpl::BrowserChildProcessHostImpl(
75 content::ProcessType type, 75 content::ProcessType type,
76 BrowserChildProcessHostDelegate* delegate) 76 BrowserChildProcessHostDelegate* delegate)
77 : data_(type), 77 : data_(type),
78 delegate_(delegate), 78 delegate_(delegate),
79 #if !defined(OS_WIN) 79 #if !defined(OS_WIN)
80 ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)), 80 ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)),
81 #endif 81 #endif
82 disconnect_was_alive_(false) { 82 disconnect_was_alive_(false) {
83 data_.id = ChildProcessHostImpl::GenerateChildProcessUniqueId(); 83 data_.id = ChildProcessHostImpl::GenerateChildProcessUniqueId();
84 84
85 child_process_host_.reset(ChildProcessHost::Create(this)); 85 child_process_host_.reset(ChildProcessHost::Create(this));
86 child_process_host_->AddFilter(new TraceMessageFilter); 86 child_process_host_->AddFilter(new TraceMessageFilter);
87 child_process_host_->AddFilter(new ProfilerMessageFilter); 87 child_process_host_->AddFilter(new ProfilerMessageFilter);
88 88
89 g_child_process_list.Get().push_back(this); 89 g_child_process_list.Get().push_back(this);
90 } 90 }
91 91
92 BrowserChildProcessHost::~BrowserChildProcessHost() { 92 BrowserChildProcessHostImpl::~BrowserChildProcessHostImpl() {
93 g_child_process_list.Get().remove(this); 93 g_child_process_list.Get().remove(this);
94 } 94 }
95 95
96 // static 96 // static
97 void BrowserChildProcessHost::TerminateAll() { 97 void BrowserChildProcessHostImpl::TerminateAll() {
98 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 98 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
99 // Make a copy since the BrowserChildProcessHost dtor mutates the original 99 // Make a copy since the BrowserChildProcessHost dtor mutates the original
100 // list. 100 // list.
101 BrowserChildProcessList copy = g_child_process_list.Get(); 101 BrowserChildProcessList copy = g_child_process_list.Get();
102 STLDeleteElements(&copy); 102 STLDeleteElements(&copy);
103 } 103 }
104 104
105 void BrowserChildProcessHost::Launch( 105 void BrowserChildProcessHostImpl::Launch(
106 #if defined(OS_WIN) 106 #if defined(OS_WIN)
107 const FilePath& exposed_dir, 107 const FilePath& exposed_dir,
108 #elif defined(OS_POSIX) 108 #elif defined(OS_POSIX)
109 bool use_zygote, 109 bool use_zygote,
110 const base::environment_vector& environ, 110 const base::environment_vector& environ,
111 #endif 111 #endif
112 CommandLine* cmd_line) { 112 CommandLine* cmd_line) {
113 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 113 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
114 114
115 content::GetContentClient()->browser()->AppendExtraCommandLineSwitches( 115 content::GetContentClient()->browser()->AppendExtraCommandLineSwitches(
116 cmd_line, data_.id); 116 cmd_line, data_.id);
117 117
118 child_process_.reset(new ChildProcessLauncher( 118 child_process_.reset(new ChildProcessLauncher(
119 #if defined(OS_WIN) 119 #if defined(OS_WIN)
120 exposed_dir, 120 exposed_dir,
121 #elif defined(OS_POSIX) 121 #elif defined(OS_POSIX)
122 use_zygote, 122 use_zygote,
123 environ, 123 environ,
124 child_process_host_->TakeClientFileDescriptor(), 124 child_process_host_->TakeClientFileDescriptor(),
125 #endif 125 #endif
126 cmd_line, 126 cmd_line,
127 this)); 127 this));
128 } 128 }
129 129
130 const ChildProcessData& BrowserChildProcessHost::GetData() const { 130 const ChildProcessData& BrowserChildProcessHostImpl::GetData() const {
131 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 131 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
132 return data_; 132 return data_;
133 } 133 }
134 134
135 ChildProcessHost* BrowserChildProcessHost::GetHost() const { 135 ChildProcessHost* BrowserChildProcessHostImpl::GetHost() const {
136 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 136 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
137 return child_process_host_.get(); 137 return child_process_host_.get();
138 } 138 }
139 139
140 base::ProcessHandle BrowserChildProcessHost::GetHandle() const { 140 base::ProcessHandle BrowserChildProcessHostImpl::GetHandle() const {
141 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 141 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
142 DCHECK(child_process_.get()) 142 DCHECK(child_process_.get())
143 << "Requesting a child process handle before launching."; 143 << "Requesting a child process handle before launching.";
144 DCHECK(child_process_->GetHandle()) 144 DCHECK(child_process_->GetHandle())
145 << "Requesting a child process handle before launch has completed OK."; 145 << "Requesting a child process handle before launch has completed OK.";
146 return child_process_->GetHandle(); 146 return child_process_->GetHandle();
147 } 147 }
148 148
149 void BrowserChildProcessHost::SetName(const string16& name) { 149 void BrowserChildProcessHostImpl::SetName(const string16& name) {
150 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 150 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
151 data_.name = name; 151 data_.name = name;
152 } 152 }
153 153
154 void BrowserChildProcessHost::SetHandle(base::ProcessHandle handle) { 154 void BrowserChildProcessHostImpl::SetHandle(base::ProcessHandle handle) {
155 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 155 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
156 data_.handle = handle; 156 data_.handle = handle;
157 } 157 }
158 158
159 void BrowserChildProcessHost::ForceShutdown() { 159 void BrowserChildProcessHostImpl::ForceShutdown() {
160 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 160 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
161 g_child_process_list.Get().remove(this); 161 g_child_process_list.Get().remove(this);
162 child_process_host_->ForceShutdown(); 162 child_process_host_->ForceShutdown();
163 } 163 }
164 164
165 void BrowserChildProcessHost::SetTerminateChildOnShutdown( 165 void BrowserChildProcessHostImpl::SetTerminateChildOnShutdown(
166 bool terminate_on_shutdown) { 166 bool terminate_on_shutdown) {
167 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 167 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
168 child_process_->SetTerminateChildOnShutdown(terminate_on_shutdown); 168 child_process_->SetTerminateChildOnShutdown(terminate_on_shutdown);
169 } 169 }
170 170
171 void BrowserChildProcessHost::Notify(int type) { 171 void BrowserChildProcessHostImpl::Notify(int type) {
172 BrowserThread::PostTask( 172 BrowserThread::PostTask(
173 BrowserThread::UI, 173 BrowserThread::UI,
174 FROM_HERE, 174 FROM_HERE,
175 base::Bind(&ChildNotificationHelper, type, data_)); 175 base::Bind(&ChildNotificationHelper, type, data_));
176 } 176 }
177 177
178 base::TerminationStatus BrowserChildProcessHost::GetTerminationStatus( 178 base::TerminationStatus BrowserChildProcessHostImpl::GetTerminationStatus(
179 int* exit_code) { 179 int* exit_code) {
180 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 180 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
181 if (!child_process_.get()) // If the delegate doesn't use Launch() helper. 181 if (!child_process_.get()) // If the delegate doesn't use Launch() helper.
182 return base::GetTerminationStatus(data_.handle, exit_code); 182 return base::GetTerminationStatus(data_.handle, exit_code);
183 return child_process_->GetChildTerminationStatus(exit_code); 183 return child_process_->GetChildTerminationStatus(exit_code);
184 } 184 }
185 185
186 bool BrowserChildProcessHost::OnMessageReceived(const IPC::Message& message) { 186 bool BrowserChildProcessHostImpl::OnMessageReceived(
187 const IPC::Message& message) {
187 return delegate_->OnMessageReceived(message); 188 return delegate_->OnMessageReceived(message);
188 } 189 }
189 190
190 void BrowserChildProcessHost::OnChannelConnected(int32 peer_pid) { 191 void BrowserChildProcessHostImpl::OnChannelConnected(int32 peer_pid) {
191 Notify(content::NOTIFICATION_CHILD_PROCESS_HOST_CONNECTED); 192 Notify(content::NOTIFICATION_CHILD_PROCESS_HOST_CONNECTED);
192 delegate_->OnChannelConnected(peer_pid); 193 delegate_->OnChannelConnected(peer_pid);
193 } 194 }
194 195
195 void BrowserChildProcessHost::OnChannelError() { 196 void BrowserChildProcessHostImpl::OnChannelError() {
196 delegate_->OnChannelError(); 197 delegate_->OnChannelError();
197 } 198 }
198 199
199 bool BrowserChildProcessHost::CanShutdown() { 200 bool BrowserChildProcessHostImpl::CanShutdown() {
200 return delegate_->CanShutdown(); 201 return delegate_->CanShutdown();
201 } 202 }
202 203
203 // Normally a ChildProcessHostDelegate deletes itself from this callback, but at 204 // Normally a ChildProcessHostDelegate deletes itself from this callback, but at
204 // this layer and below we need to have the final child process exit code to 205 // this layer and below we need to have the final child process exit code to
205 // properly bucket crashes vs kills. On Windows we can do this if we wait until 206 // properly bucket crashes vs kills. On Windows we can do this if we wait until
206 // the process handle is signaled; on the rest of the platforms, we schedule a 207 // the process handle is signaled; on the rest of the platforms, we schedule a
207 // delayed task to wait for an exit code. However, this means that this method 208 // delayed task to wait for an exit code. However, this means that this method
208 // may be called twice: once from the actual channel error and once from 209 // may be called twice: once from the actual channel error and once from
209 // OnWaitableEventSignaled() or the delayed task. 210 // OnWaitableEventSignaled() or the delayed task.
210 void BrowserChildProcessHost::OnChildDisconnected() { 211 void BrowserChildProcessHostImpl::OnChildDisconnected() {
211 DCHECK(data_.handle != base::kNullProcessHandle); 212 DCHECK(data_.handle != base::kNullProcessHandle);
212 int exit_code; 213 int exit_code;
213 base::TerminationStatus status = GetTerminationStatus(&exit_code); 214 base::TerminationStatus status = GetTerminationStatus(&exit_code);
214 switch (status) { 215 switch (status) {
215 case base::TERMINATION_STATUS_PROCESS_CRASHED: 216 case base::TERMINATION_STATUS_PROCESS_CRASHED:
216 case base::TERMINATION_STATUS_ABNORMAL_TERMINATION: { 217 case base::TERMINATION_STATUS_ABNORMAL_TERMINATION: {
217 delegate_->OnProcessCrashed(exit_code); 218 delegate_->OnProcessCrashed(exit_code);
218 // Report that this child process crashed. 219 // Report that this child process crashed.
219 Notify(content::NOTIFICATION_CHILD_PROCESS_CRASHED); 220 Notify(content::NOTIFICATION_CHILD_PROCESS_CRASHED);
220 UMA_HISTOGRAM_ENUMERATION("ChildProcess.Crashed", 221 UMA_HISTOGRAM_ENUMERATION("ChildProcess.Crashed",
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
253 child_watcher_.StartWatching( 254 child_watcher_.StartWatching(
254 new base::WaitableEvent(data_.handle), this); 255 new base::WaitableEvent(data_.handle), this);
255 #else 256 #else
256 // On non-Windows platforms, give the child process some time to die after 257 // On non-Windows platforms, give the child process some time to die after
257 // disconnecting the channel so that the exit code and termination status 258 // disconnecting the channel so that the exit code and termination status
258 // become available. This is best effort -- if the process doesn't die 259 // become available. This is best effort -- if the process doesn't die
259 // within the time limit, this object gets destroyed. 260 // within the time limit, this object gets destroyed.
260 const int kExitCodeWaitMs = 250; 261 const int kExitCodeWaitMs = 250;
261 MessageLoop::current()->PostDelayedTask( 262 MessageLoop::current()->PostDelayedTask(
262 FROM_HERE, 263 FROM_HERE,
263 base::Bind(&BrowserChildProcessHost::OnChildDisconnected, 264 base::Bind(&BrowserChildProcessHostImpl::OnChildDisconnected,
264 task_factory_.GetWeakPtr()), 265 task_factory_.GetWeakPtr()),
265 kExitCodeWaitMs); 266 kExitCodeWaitMs);
266 #endif 267 #endif
267 return; 268 return;
268 } 269 }
269 270
270 default: 271 default:
271 break; 272 break;
272 } 273 }
273 UMA_HISTOGRAM_ENUMERATION("ChildProcess.Disconnected", 274 UMA_HISTOGRAM_ENUMERATION("ChildProcess.Disconnected",
274 data_.type, 275 data_.type,
275 content::PROCESS_TYPE_MAX); 276 content::PROCESS_TYPE_MAX);
276 // Notify in the main loop of the disconnection. 277 // Notify in the main loop of the disconnection.
277 Notify(content::NOTIFICATION_CHILD_PROCESS_HOST_DISCONNECTED); 278 Notify(content::NOTIFICATION_CHILD_PROCESS_HOST_DISCONNECTED);
278 delete delegate_; // Will delete us 279 delete delegate_; // Will delete us
279 } 280 }
280 281
281 // The child process handle has been signaled so the exit code is finally 282 // The child process handle has been signaled so the exit code is finally
282 // available. Unfortunately STILL_ACTIVE (0x103) is a valid exit code in 283 // available. Unfortunately STILL_ACTIVE (0x103) is a valid exit code in
283 // which case we should not call OnChildDisconnected() or else we will be 284 // which case we should not call OnChildDisconnected() or else we will be
284 // waiting forever. 285 // waiting forever.
285 void BrowserChildProcessHost::OnWaitableEventSignaled( 286 void BrowserChildProcessHostImpl::OnWaitableEventSignaled(
286 base::WaitableEvent* waitable_event) { 287 base::WaitableEvent* waitable_event) {
287 #if defined (OS_WIN) 288 #if defined (OS_WIN)
288 unsigned long exit_code = 0; 289 unsigned long exit_code = 0;
289 GetExitCodeProcess(waitable_event->Release(), &exit_code); 290 GetExitCodeProcess(waitable_event->Release(), &exit_code);
290 delete waitable_event; 291 delete waitable_event;
291 if (exit_code == STILL_ACTIVE) { 292 if (exit_code == STILL_ACTIVE) {
292 delete delegate_; // Will delete us 293 delete delegate_; // Will delete us
293 } else { 294 } else {
294 BrowserChildProcessHost::OnChildDisconnected(); 295 BrowserChildProcessHostImpl::OnChildDisconnected();
295 } 296 }
296 #endif 297 #endif
297 } 298 }
298 299
299 bool BrowserChildProcessHost::Send(IPC::Message* message) { 300 bool BrowserChildProcessHostImpl::Send(IPC::Message* message) {
300 return child_process_host_->Send(message); 301 return child_process_host_->Send(message);
301 } 302 }
302 303
303 void BrowserChildProcessHost::ShutdownStarted() { 304 void BrowserChildProcessHostImpl::ShutdownStarted() {
304 // Must remove the process from the list now, in case it gets used for a 305 // Must remove the process from the list now, in case it gets used for a
305 // new instance before our watcher tells us that the process terminated. 306 // new instance before our watcher tells us that the process terminated.
306 g_child_process_list.Get().remove(this); 307 g_child_process_list.Get().remove(this);
307 } 308 }
308 309
309 310
310 void BrowserChildProcessHost::OnProcessLaunched() { 311 void BrowserChildProcessHostImpl::OnProcessLaunched() {
311 if (!child_process_->GetHandle()) { 312 if (!child_process_->GetHandle()) {
312 delete delegate_; // Will delete us 313 delete delegate_; // Will delete us
313 return; 314 return;
314 } 315 }
315 data_.handle = child_process_->GetHandle(); 316 data_.handle = child_process_->GetHandle();
316 delegate_->OnProcessLaunched(); 317 delegate_->OnProcessLaunched();
317 } 318 }
OLDNEW
« no previous file with comments | « content/browser/browser_child_process_host_impl.h ('k') | content/browser/browser_process_sub_thread.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698