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

Side by Side Diff: chrome/browser/child_process_host.cc

Issue 1625015: Refactor ChildProcess and related classes to create a framework outside of br... (Closed) Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: Created 10 years, 8 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
« no previous file with comments | « chrome/browser/child_process_host.h ('k') | chrome/browser/child_process_launcher.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) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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/browser/child_process_host.h" 5 #include "chrome/browser/child_process_host.h"
6 6
7 #include "base/command_line.h" 7 #include "base/command_line.h"
8 #include "base/compiler_specific.h" 8 #include "base/compiler_specific.h"
9 #include "base/file_path.h" 9 #include "base/file_path.h"
10 #include "base/histogram.h" 10 #include "base/histogram.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/mp/mp_messages.h"
12 #include "base/path_service.h" 13 #include "base/path_service.h"
13 #include "base/process_util.h" 14 #include "base/process_util.h"
14 #include "base/singleton.h" 15 #include "base/singleton.h"
15 #include "base/string_util.h" 16 #include "base/string_util.h"
16 #include "base/waitable_event.h" 17 #include "base/waitable_event.h"
17 #include "chrome/browser/chrome_thread.h" 18 #include "chrome/browser/chrome_thread.h"
18 #include "chrome/common/chrome_constants.h" 19 #include "chrome/common/chrome_constants.h"
19 #include "chrome/common/chrome_paths_internal.h" 20 #include "chrome/common/chrome_paths_internal.h"
20 #include "chrome/common/chrome_switches.h" 21 #include "chrome/common/chrome_switches.h"
21 #include "chrome/common/env_vars.h" 22 #include "chrome/common/env_vars.h"
22 #include "chrome/common/notification_service.h" 23 #include "chrome/common/notification_service.h"
23 #include "chrome/common/notification_type.h" 24 #include "chrome/common/notification_type.h"
24 #include "chrome/common/plugin_messages.h"
25 #include "chrome/common/process_watcher.h" 25 #include "chrome/common/process_watcher.h"
26 #include "chrome/common/result_codes.h" 26 #include "chrome/common/result_codes.h"
27 #include "chrome/installer/util/google_update_settings.h" 27 #include "chrome/installer/util/google_update_settings.h"
28 28
29 #if defined(OS_LINUX) 29 #if defined(OS_LINUX)
30 #include "base/linux_util.h" 30 #include "base/linux_util.h"
31 #endif // OS_LINUX 31 #endif // OS_LINUX
32 32
33 #if defined(OS_POSIX) 33 #if defined(OS_POSIX)
34 // This is defined in chrome/browser/google_update_settings_posix.cc. It's the 34 // This is defined in chrome/browser/google_update_settings_posix.cc. It's the
(...skipping 28 matching lines...) Expand all
63 NotificationType notification_type_; 63 NotificationType notification_type_;
64 ChildProcessInfo info_; 64 ChildProcessInfo info_;
65 }; 65 };
66 66
67 } // namespace 67 } // namespace
68 68
69 69
70 ChildProcessHost::ChildProcessHost( 70 ChildProcessHost::ChildProcessHost(
71 ProcessType type, ResourceDispatcherHost* resource_dispatcher_host) 71 ProcessType type, ResourceDispatcherHost* resource_dispatcher_host)
72 : Receiver(type, -1), 72 : Receiver(type, -1),
73 ALLOW_THIS_IN_INITIALIZER_LIST(listener_(this)), 73 base::MpChildProcessHost(&context_),
74 resource_dispatcher_host_(resource_dispatcher_host), 74 resource_dispatcher_host_(resource_dispatcher_host) {
75 opening_channel_(false) {
76 Singleton<ChildProcessList>::get()->push_back(this);
77 } 75 }
78 76
79 77
80 ChildProcessHost::~ChildProcessHost() { 78 ChildProcessHost::~ChildProcessHost() {
81 Singleton<ChildProcessList>::get()->remove(this);
82
83 if (resource_dispatcher_host_) 79 if (resource_dispatcher_host_)
84 resource_dispatcher_host_->CancelRequestsForProcess(id()); 80 resource_dispatcher_host_->CancelRequestsForProcess(id());
85 } 81 }
86 82
87 // static 83 // static
88 FilePath ChildProcessHost::GetChildPath(bool allow_self) { 84 FilePath ChildProcessHost::GetChildPath(bool allow_self) {
89 FilePath child_path; 85 FilePath child_path;
90 86
91 child_path = CommandLine::ForCurrentProcess()->GetSwitchValuePath( 87 child_path = CommandLine::ForCurrentProcess()->GetSwitchValuePath(
92 switches::kBrowserSubprocessPath); 88 switches::kBrowserSubprocessPath);
(...skipping 30 matching lines...) Expand all
123 "," + 119 "," +
124 base::GetLinuxDistro())); 120 base::GetLinuxDistro()));
125 } 121 }
126 #elif defined(OS_MACOSX) 122 #elif defined(OS_MACOSX)
127 if (GoogleUpdateSettings::GetCollectStatsConsent()) 123 if (GoogleUpdateSettings::GetCollectStatsConsent())
128 command_line->AppendSwitchWithValue(switches::kEnableCrashReporter, 124 command_line->AppendSwitchWithValue(switches::kEnableCrashReporter,
129 ASCIIToWide(google_update::posix_guid)); 125 ASCIIToWide(google_update::posix_guid));
130 #endif // OS_MACOSX 126 #endif // OS_MACOSX
131 } 127 }
132 128
133 void ChildProcessHost::Launch( 129 bool ChildProcessHost::Send(IPC::Message* msg) {
134 #if defined(OS_WIN) 130 return base::MpChildProcessHost::Send(msg);
135 const FilePath& exposed_dir,
136 #elif defined(OS_POSIX)
137 bool use_zygote,
138 const base::environment_vector& environ,
139 #endif
140 CommandLine* cmd_line) {
141 child_process_.reset(new ChildProcessLauncher(
142 #if defined(OS_WIN)
143 exposed_dir,
144 #elif defined(OS_POSIX)
145 use_zygote,
146 environ,
147 channel_->GetClientFileDescriptor(),
148 #endif
149 cmd_line,
150 &listener_));
151 } 131 }
152 132
153 bool ChildProcessHost::CreateChannel() { 133 void ChildProcessHost::Notify(
154 channel_id_ = GenerateRandomChannelID(this); 134 base::MpChildProcessHost::MpNotificationType type) {
155 channel_.reset(new IPC::Channel( 135 NotificationType chrome_type(NotificationType::ALL);
156 channel_id_, IPC::Channel::MODE_SERVER, &listener_)); 136 switch (type) {
157 if (!channel_->Connect()) 137 case base::MpChildProcessHost::CHILD_INSTANCE_CREATED:
158 return false; 138 chrome_type = NotificationType::CHILD_INSTANCE_CREATED;
159 139 break;
160 opening_channel_ = true; 140 case base::MpChildProcessHost::CHILD_PROCESS_CRASHED:
161 141 chrome_type = NotificationType::CHILD_PROCESS_CRASHED;
162 return true; 142 break;
143 case base::MpChildProcessHost::CHILD_PROCESS_HOST_CONNECTED:
144 chrome_type = NotificationType::CHILD_PROCESS_HOST_CONNECTED;
145 break;
146 case base::MpChildProcessHost::CHILD_PROCESS_HOST_DISCONNECTED:
147 chrome_type = NotificationType::CHILD_PROCESS_HOST_DISCONNECTED;
148 break;
149 default:
150 NOTREACHED();
151 }
152 ChromeThread::PostTask(
153 ChromeThread::UI, FROM_HERE,
154 new ChildNotificationTask(chrome_type, this));
163 } 155 }
164 156
165 void ChildProcessHost::InstanceCreated() { 157 bool ChildProcessHost::OnDispatchMessageReceived(const IPC::Message& msg,
166 Notify(NotificationType::CHILD_INSTANCE_CREATED); 158 bool *msg_is_ok) {
159 return resource_dispatcher_host_->OnMessageReceived(msg, this, msg_is_ok);
167 } 160 }
168 161
169 bool ChildProcessHost::Send(IPC::Message* msg) { 162 void ChildProcessHost::OnProcessLaunched() {
170 if (!channel_.get()) { 163 set_handle(GetHandle());
171 delete msg;
172 return false;
173 }
174 return channel_->Send(msg);
175 } 164 }
176 165
177 void ChildProcessHost::Notify(NotificationType type) { 166 int ChildProcessHost::GetType() {
178 ChromeThread::PostTask( 167 return type();
179 ChromeThread::UI, FROM_HERE, new ChildNotificationTask(type, this));
180 } 168 }
181 169
182 bool ChildProcessHost::DidChildCrash() {
183 return child_process_->DidProcessCrash();
184 }
185
186 void ChildProcessHost::OnChildDied() {
187 if (handle() != base::kNullProcessHandle) {
188 bool did_crash = DidChildCrash();
189 if (did_crash) {
190 OnProcessCrashed();
191 // Report that this child process crashed.
192 Notify(NotificationType::CHILD_PROCESS_CRASHED);
193 UMA_HISTOGRAM_COUNTS("ChildProcess.Crashes", this->type());
194 }
195 // Notify in the main loop of the disconnection.
196 Notify(NotificationType::CHILD_PROCESS_HOST_DISCONNECTED);
197 }
198
199 delete this;
200 }
201
202 ChildProcessHost::ListenerHook::ListenerHook(ChildProcessHost* host)
203 : host_(host) {
204 }
205
206 void ChildProcessHost::ListenerHook::OnMessageReceived(
207 const IPC::Message& msg) {
208 #ifdef IPC_MESSAGE_LOG_ENABLED
209 IPC::Logging* logger = IPC::Logging::current();
210 if (msg.type() == IPC_LOGGING_ID) {
211 logger->OnReceivedLoggingMessage(msg);
212 return;
213 }
214
215 if (logger->Enabled())
216 logger->OnPreDispatchMessage(msg);
217 #endif
218
219 bool msg_is_ok = true;
220 bool handled = false;
221
222 if (host_->resource_dispatcher_host_)
223 host_->resource_dispatcher_host_->OnMessageReceived(
224 msg, host_, &msg_is_ok);
225
226 if (!handled) {
227 if (msg.type() == PluginProcessHostMsg_ShutdownRequest::ID) {
228 // Must remove the process from the list now, in case it gets used for a
229 // new instance before our watcher tells us that the process terminated.
230 Singleton<ChildProcessList>::get()->remove(host_);
231 if (host_->CanShutdown())
232 host_->Send(new PluginProcessMsg_Shutdown());
233 } else {
234 host_->OnMessageReceived(msg);
235 }
236 }
237
238 if (!msg_is_ok)
239 base::KillProcess(host_->handle(), ResultCodes::KILLED_BAD_MESSAGE, false);
240
241 #ifdef IPC_MESSAGE_LOG_ENABLED
242 if (logger->Enabled())
243 logger->OnPostDispatchMessage(msg, host_->channel_id_);
244 #endif
245 }
246
247 void ChildProcessHost::ListenerHook::OnChannelConnected(int32 peer_pid) {
248 host_->opening_channel_ = false;
249 host_->OnChannelConnected(peer_pid);
250
251 #if defined(IPC_MESSAGE_LOG_ENABLED)
252 bool enabled = IPC::Logging::current()->Enabled();
253 host_->Send(new PluginProcessMsg_SetIPCLoggingEnabled(enabled));
254 #endif
255
256 host_->Send(new PluginProcessMsg_AskBeforeShutdown());
257
258 // Notify in the main loop of the connection.
259 host_->Notify(NotificationType::CHILD_PROCESS_HOST_CONNECTED);
260 }
261
262 void ChildProcessHost::ListenerHook::OnChannelError() {
263 host_->opening_channel_ = false;
264 host_->OnChannelError();
265
266 // This will delete host_, which will also destroy this!
267 host_->OnChildDied();
268 }
269
270 void ChildProcessHost::ListenerHook::OnProcessLaunched() {
271 if (!host_->child_process_->GetHandle()) {
272 delete this;
273 return;
274 }
275
276 host_->set_handle(host_->child_process_->GetHandle());
277 host_->OnProcessLaunched();
278 }
279
280
281 ChildProcessHost::Iterator::Iterator() 170 ChildProcessHost::Iterator::Iterator()
282 : all_(true), type_(UNKNOWN_PROCESS) { 171 : all_(true), type_(UNKNOWN_PROCESS) {
283 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)) << 172 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)) <<
284 "ChildProcessInfo::Iterator must be used on the IO thread."; 173 "ChildProcessInfo::Iterator must be used on the IO thread.";
285 iterator_ = Singleton<ChildProcessList>::get()->begin(); 174 iterator_ = Singleton<ChildProcessList>::get()->begin();
286 } 175 }
287 176
288 ChildProcessHost::Iterator::Iterator(ProcessType type) 177 ChildProcessHost::Iterator::Iterator(ProcessType type)
289 : all_(false), type_(type) { 178 : all_(false), type_(type) {
290 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)) << 179 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)) <<
(...skipping 14 matching lines...) Expand all
305 194
306 return *iterator_; 195 return *iterator_;
307 } while (true); 196 } while (true);
308 197
309 return NULL; 198 return NULL;
310 } 199 }
311 200
312 bool ChildProcessHost::Iterator::Done() { 201 bool ChildProcessHost::Iterator::Done() {
313 return iterator_ == Singleton<ChildProcessList>::get()->end(); 202 return iterator_ == Singleton<ChildProcessList>::get()->end();
314 } 203 }
315
316 void ChildProcessHost::ForceShutdown() {
317 Singleton<ChildProcessList>::get()->remove(this);
318 Send(new PluginProcessMsg_Shutdown());
319 }
OLDNEW
« no previous file with comments | « chrome/browser/child_process_host.h ('k') | chrome/browser/child_process_launcher.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698