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

Side by Side Diff: content/common/child_process_host_impl.cc

Issue 8787004: Make ChildProcessHost be used through an interface in content/public, instead of by inheritence. (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
« no previous file with comments | « content/common/child_process_host_impl.h ('k') | content/content_common.gypi » ('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) 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/common/child_process_host.h" 5 #include "content/common/child_process_host_impl.h"
6 6
7 #include <limits> 7 #include <limits>
8 8
9 #include "base/atomicops.h" 9 #include "base/atomicops.h"
10 #include "base/command_line.h" 10 #include "base/command_line.h"
11 #include "base/file_path.h" 11 #include "base/file_path.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"
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
67 .Append(kContentsName) 67 .Append(kContentsName)
68 .Append(kMacOSName) 68 .Append(kMacOSName)
69 .Append(new_basename); 69 .Append(new_basename);
70 70
71 return new_path; 71 return new_path;
72 } 72 }
73 73
74 } // namespace 74 } // namespace
75 #endif // OS_MACOSX 75 #endif // OS_MACOSX
76 76
77 ChildProcessHost::ChildProcessHost(content::ChildProcessHostDelegate* delegate) 77 namespace content {
78 : delegate_(delegate),
79 peer_handle_(base::kNullProcessHandle),
80 opening_channel_(false) {
81 #if defined(OS_WIN)
82 AddFilter(new FontCacheDispatcher());
83 #endif
84 }
85 78
86 ChildProcessHost::~ChildProcessHost() { 79 // static
87 for (size_t i = 0; i < filters_.size(); ++i) { 80 ChildProcessHost* ChildProcessHost::Create(ChildProcessHostDelegate* delegate) {
88 filters_[i]->OnChannelClosing(); 81 return new ChildProcessHostImpl(delegate);
89 filters_[i]->OnFilterRemoved();
90 }
91
92 base::CloseProcessHandle(peer_handle_);
93 }
94
95 void ChildProcessHost::AddFilter(IPC::ChannelProxy::MessageFilter* filter) {
96 filters_.push_back(filter);
97
98 if (channel_.get())
99 filter->OnFilterAdded(channel_.get());
100 } 82 }
101 83
102 // static 84 // static
103 FilePath ChildProcessHost::GetChildPath(int flags) { 85 FilePath ChildProcessHost::GetChildPath(int flags) {
104 FilePath child_path; 86 FilePath child_path;
105 87
106 child_path = CommandLine::ForCurrentProcess()->GetSwitchValuePath( 88 child_path = CommandLine::ForCurrentProcess()->GetSwitchValuePath(
107 switches::kBrowserSubprocessPath); 89 switches::kBrowserSubprocessPath);
108 90
109 #if defined(OS_LINUX) 91 #if defined(OS_LINUX)
(...skipping 26 matching lines...) Expand all
136 // non-executable heap, but the "EH" feature is provided to allow code 118 // non-executable heap, but the "EH" feature is provided to allow code
137 // intolerant of a non-executable heap to work properly on 10.7. This 119 // intolerant of a non-executable heap to work properly on 10.7. This
138 // results in Chromium Helper EH.app or Google Chrome Helper EH.app. 120 // results in Chromium Helper EH.app or Google Chrome Helper EH.app.
139 child_path = TransformPathForFeature(child_path, "EH"); 121 child_path = TransformPathForFeature(child_path, "EH");
140 } 122 }
141 #endif 123 #endif
142 124
143 return child_path; 125 return child_path;
144 } 126 }
145 127
146 void ChildProcessHost::ForceShutdown() { 128 ChildProcessHostImpl::ChildProcessHostImpl(ChildProcessHostDelegate* delegate)
129 : delegate_(delegate),
130 peer_handle_(base::kNullProcessHandle),
131 opening_channel_(false) {
132 #if defined(OS_WIN)
133 AddFilter(new FontCacheDispatcher());
134 #endif
135 }
136
137 ChildProcessHostImpl::~ChildProcessHostImpl() {
138 for (size_t i = 0; i < filters_.size(); ++i) {
139 filters_[i]->OnChannelClosing();
140 filters_[i]->OnFilterRemoved();
141 }
142
143 base::CloseProcessHandle(peer_handle_);
144 }
145
146 void ChildProcessHostImpl::AddFilter(IPC::ChannelProxy::MessageFilter* filter) {
147 filters_.push_back(filter);
148
149 if (channel_.get())
150 filter->OnFilterAdded(channel_.get());
151 }
152
153 void ChildProcessHostImpl::ForceShutdown() {
147 Send(new ChildProcessMsg_Shutdown()); 154 Send(new ChildProcessMsg_Shutdown());
148 } 155 }
149 156
150 bool ChildProcessHost::CreateChannel() { 157 std::string ChildProcessHostImpl::CreateChannel() {
151 channel_id_ = GenerateRandomChannelID(this); 158 channel_id_ = GenerateRandomChannelID(this);
152 channel_.reset(new IPC::Channel( 159 channel_.reset(new IPC::Channel(
153 channel_id_, IPC::Channel::MODE_SERVER, this)); 160 channel_id_, IPC::Channel::MODE_SERVER, this));
154 if (!channel_->Connect()) 161 if (!channel_->Connect())
155 return false; 162 return std::string();
156 163
157 for (size_t i = 0; i < filters_.size(); ++i) 164 for (size_t i = 0; i < filters_.size(); ++i)
158 filters_[i]->OnFilterAdded(channel_.get()); 165 filters_[i]->OnFilterAdded(channel_.get());
159 166
160 // Make sure these messages get sent first. 167 // Make sure these messages get sent first.
161 #if defined(IPC_MESSAGE_LOG_ENABLED) 168 #if defined(IPC_MESSAGE_LOG_ENABLED)
162 bool enabled = IPC::Logging::GetInstance()->Enabled(); 169 bool enabled = IPC::Logging::GetInstance()->Enabled();
163 Send(new ChildProcessMsg_SetIPCLoggingEnabled(enabled)); 170 Send(new ChildProcessMsg_SetIPCLoggingEnabled(enabled));
164 #endif 171 #endif
165 172
166 Send(new ChildProcessMsg_AskBeforeShutdown()); 173 Send(new ChildProcessMsg_AskBeforeShutdown());
167 174
168 opening_channel_ = true; 175 opening_channel_ = true;
169 176
170 return true; 177 return channel_id_;
171 } 178 }
172 179
173 bool ChildProcessHost::Send(IPC::Message* message) { 180 bool ChildProcessHostImpl::IsChannelOpening() {
181 return opening_channel_;
182 }
183
184 #if defined(OS_POSIX)
185 int ChildProcessHostImpl::TakeClientFileDescriptor() {
186 return channel_->TakeClientFileDescriptor();
187 }
188 #endif
189
190 bool ChildProcessHostImpl::Send(IPC::Message* message) {
174 if (!channel_.get()) { 191 if (!channel_.get()) {
175 delete message; 192 delete message;
176 return false; 193 return false;
177 } 194 }
178 return channel_->Send(message); 195 return channel_->Send(message);
179 } 196 }
180 197
181 void ChildProcessHost::AllocateSharedMemory( 198 void ChildProcessHostImpl::AllocateSharedMemory(
182 uint32 buffer_size, base::ProcessHandle child_process_handle, 199 uint32 buffer_size, base::ProcessHandle child_process_handle,
183 base::SharedMemoryHandle* shared_memory_handle) { 200 base::SharedMemoryHandle* shared_memory_handle) {
184 base::SharedMemory shared_buf; 201 base::SharedMemory shared_buf;
185 if (!shared_buf.CreateAndMapAnonymous(buffer_size)) { 202 if (!shared_buf.CreateAndMapAnonymous(buffer_size)) {
186 *shared_memory_handle = base::SharedMemory::NULLHandle(); 203 *shared_memory_handle = base::SharedMemory::NULLHandle();
187 NOTREACHED() << "Cannot map shared memory buffer"; 204 NOTREACHED() << "Cannot map shared memory buffer";
188 return; 205 return;
189 } 206 }
190 shared_buf.GiveToProcess(child_process_handle, shared_memory_handle); 207 shared_buf.GiveToProcess(child_process_handle, shared_memory_handle);
191 } 208 }
192 209
193 std::string ChildProcessHost::GenerateRandomChannelID(void* instance) { 210 std::string ChildProcessHostImpl::GenerateRandomChannelID(void* instance) {
194 // Note: the string must start with the current process id, this is how 211 // Note: the string must start with the current process id, this is how
195 // child processes determine the pid of the parent. 212 // child processes determine the pid of the parent.
196 // Build the channel ID. This is composed of a unique identifier for the 213 // Build the channel ID. This is composed of a unique identifier for the
197 // parent browser process, an identifier for the child instance, and a random 214 // parent browser process, an identifier for the child instance, and a random
198 // component. We use a random component so that a hacked child process can't 215 // component. We use a random component so that a hacked child process can't
199 // cause denial of service by causing future named pipe creation to fail. 216 // cause denial of service by causing future named pipe creation to fail.
200 return base::StringPrintf("%d.%p.%d", 217 return base::StringPrintf("%d.%p.%d",
201 base::GetCurrentProcId(), instance, 218 base::GetCurrentProcId(), instance,
202 base::RandInt(0, std::numeric_limits<int>::max())); 219 base::RandInt(0, std::numeric_limits<int>::max()));
203 } 220 }
204 221
205 int ChildProcessHost::GenerateChildProcessUniqueId() { 222 int ChildProcessHostImpl::GenerateChildProcessUniqueId() {
206 // This function must be threadsafe. 223 // This function must be threadsafe.
207 static base::subtle::Atomic32 last_unique_child_id = 0; 224 static base::subtle::Atomic32 last_unique_child_id = 0;
208 return base::subtle::NoBarrier_AtomicIncrement(&last_unique_child_id, 1); 225 return base::subtle::NoBarrier_AtomicIncrement(&last_unique_child_id, 1);
209 } 226 }
210 227
211 bool ChildProcessHost::OnMessageReceived(const IPC::Message& msg) { 228 bool ChildProcessHostImpl::OnMessageReceived(const IPC::Message& msg) {
212 #ifdef IPC_MESSAGE_LOG_ENABLED 229 #ifdef IPC_MESSAGE_LOG_ENABLED
213 IPC::Logging* logger = IPC::Logging::GetInstance(); 230 IPC::Logging* logger = IPC::Logging::GetInstance();
214 if (msg.type() == IPC_LOGGING_ID) { 231 if (msg.type() == IPC_LOGGING_ID) {
215 logger->OnReceivedLoggingMessage(msg); 232 logger->OnReceivedLoggingMessage(msg);
216 return true; 233 return true;
217 } 234 }
218 235
219 if (logger->Enabled()) 236 if (logger->Enabled())
220 logger->OnPreDispatchMessage(msg); 237 logger->OnPreDispatchMessage(msg);
221 #endif 238 #endif
222 239
223 bool handled = false; 240 bool handled = false;
224 for (size_t i = 0; i < filters_.size(); ++i) { 241 for (size_t i = 0; i < filters_.size(); ++i) {
225 if (filters_[i]->OnMessageReceived(msg)) { 242 if (filters_[i]->OnMessageReceived(msg)) {
226 handled = true; 243 handled = true;
227 break; 244 break;
228 } 245 }
229 } 246 }
230 247
231 if (!handled) { 248 if (!handled) {
232 handled = true; 249 handled = true;
233 IPC_BEGIN_MESSAGE_MAP(ChildProcessHost, msg) 250 IPC_BEGIN_MESSAGE_MAP(ChildProcessHostImpl, msg)
234 IPC_MESSAGE_HANDLER(ChildProcessHostMsg_ShutdownRequest, 251 IPC_MESSAGE_HANDLER(ChildProcessHostMsg_ShutdownRequest,
235 OnShutdownRequest) 252 OnShutdownRequest)
236 IPC_MESSAGE_HANDLER(ChildProcessHostMsg_SyncAllocateSharedMemory, 253 IPC_MESSAGE_HANDLER(ChildProcessHostMsg_SyncAllocateSharedMemory,
237 OnAllocateSharedMemory) 254 OnAllocateSharedMemory)
238 IPC_MESSAGE_UNHANDLED(handled = false) 255 IPC_MESSAGE_UNHANDLED(handled = false)
239 IPC_END_MESSAGE_MAP() 256 IPC_END_MESSAGE_MAP()
240 257
241 if (!handled) 258 if (!handled)
242 handled = delegate_->OnMessageReceived(msg); 259 handled = delegate_->OnMessageReceived(msg);
243 } 260 }
244 261
245 #ifdef IPC_MESSAGE_LOG_ENABLED 262 #ifdef IPC_MESSAGE_LOG_ENABLED
246 if (logger->Enabled()) 263 if (logger->Enabled())
247 logger->OnPostDispatchMessage(msg, channel_id_); 264 logger->OnPostDispatchMessage(msg, channel_id_);
248 #endif 265 #endif
249 return handled; 266 return handled;
250 } 267 }
251 268
252 void ChildProcessHost::OnChannelConnected(int32 peer_pid) { 269 void ChildProcessHostImpl::OnChannelConnected(int32 peer_pid) {
253 if (!base::OpenProcessHandle(peer_pid, &peer_handle_)) { 270 if (!base::OpenProcessHandle(peer_pid, &peer_handle_)) {
254 NOTREACHED(); 271 NOTREACHED();
255 } 272 }
256 opening_channel_ = false; 273 opening_channel_ = false;
257 delegate_->OnChannelConnected(peer_pid); 274 delegate_->OnChannelConnected(peer_pid);
258 for (size_t i = 0; i < filters_.size(); ++i) 275 for (size_t i = 0; i < filters_.size(); ++i)
259 filters_[i]->OnChannelConnected(peer_pid); 276 filters_[i]->OnChannelConnected(peer_pid);
260 } 277 }
261 278
262 void ChildProcessHost::OnChannelError() { 279 void ChildProcessHostImpl::OnChannelError() {
263 opening_channel_ = false; 280 opening_channel_ = false;
264 delegate_->OnChannelError(); 281 delegate_->OnChannelError();
265 282
266 for (size_t i = 0; i < filters_.size(); ++i) 283 for (size_t i = 0; i < filters_.size(); ++i)
267 filters_[i]->OnChannelError(); 284 filters_[i]->OnChannelError();
268 285
269 // This will delete host_, which will also destroy this! 286 // This will delete host_, which will also destroy this!
270 delegate_->OnChildDisconnected(); 287 delegate_->OnChildDisconnected();
271 } 288 }
272 289
273 void ChildProcessHost::OnAllocateSharedMemory( 290 void ChildProcessHostImpl::OnAllocateSharedMemory(
274 uint32 buffer_size, 291 uint32 buffer_size,
275 base::SharedMemoryHandle* handle) { 292 base::SharedMemoryHandle* handle) {
276 AllocateSharedMemory(buffer_size, peer_handle_, handle); 293 AllocateSharedMemory(buffer_size, peer_handle_, handle);
277 } 294 }
278 295
279 void ChildProcessHost::OnShutdownRequest() { 296 void ChildProcessHostImpl::OnShutdownRequest() {
280 if (delegate_->CanShutdown()) 297 if (delegate_->CanShutdown())
281 Send(new ChildProcessMsg_Shutdown()); 298 Send(new ChildProcessMsg_Shutdown());
282 } 299 }
300
301 } // namespace content
OLDNEW
« no previous file with comments | « content/common/child_process_host_impl.h ('k') | content/content_common.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698