OLD | NEW |
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.h" |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/file_path.h" | 8 #include "base/file_path.h" |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
11 #include "base/path_service.h" | 11 #include "base/path_service.h" |
| 12 #include "base/process_util.h" |
12 #include "base/third_party/dynamic_annotations/dynamic_annotations.h" | 13 #include "base/third_party/dynamic_annotations/dynamic_annotations.h" |
13 #include "content/common/child_process_info.h" | 14 #include "content/common/child_process_info.h" |
14 #include "content/common/child_process_messages.h" | 15 #include "content/common/child_process_messages.h" |
15 #include "content/common/content_paths.h" | 16 #include "content/common/content_paths.h" |
16 #include "content/common/content_switches.h" | 17 #include "content/common/content_switches.h" |
17 #include "ipc/ipc_logging.h" | 18 #include "ipc/ipc_logging.h" |
18 | 19 |
19 #if defined(OS_LINUX) | 20 #if defined(OS_LINUX) |
20 #include "base/linux_util.h" | 21 #include "base/linux_util.h" |
21 #endif // OS_LINUX | 22 #endif // OS_LINUX |
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
257 } | 258 } |
258 | 259 |
259 // static | 260 // static |
260 void ChildProcessHost::ReleaseCachedFonts(int pid) { | 261 void ChildProcessHost::ReleaseCachedFonts(int pid) { |
261 // Release cached fonts that requested from a pid by decrementing the ref | 262 // Release cached fonts that requested from a pid by decrementing the ref |
262 // count. When ref count is zero, the handles are released. | 263 // count. When ref count is zero, the handles are released. |
263 ChildProcessHost::FontCache::GetInstance()->ReleaseCachedFonts(pid); | 264 ChildProcessHost::FontCache::GetInstance()->ReleaseCachedFonts(pid); |
264 } | 265 } |
265 #endif // OS_WIN | 266 #endif // OS_WIN |
266 | 267 |
| 268 void ChildProcessHost::ForceShutdown() { |
| 269 Send(new ChildProcessMsg_Shutdown()); |
| 270 } |
267 | 271 |
268 bool ChildProcessHost::CreateChannel() { | 272 bool ChildProcessHost::CreateChannel() { |
269 channel_id_ = ChildProcessInfo::GenerateRandomChannelID(this); | 273 channel_id_ = ChildProcessInfo::GenerateRandomChannelID(this); |
270 channel_.reset(new IPC::Channel( | 274 channel_.reset(new IPC::Channel( |
271 channel_id_, IPC::Channel::MODE_SERVER, &listener_)); | 275 channel_id_, IPC::Channel::MODE_SERVER, &listener_)); |
272 if (!channel_->Connect()) | 276 if (!channel_->Connect()) |
273 return false; | 277 return false; |
274 | 278 |
275 for (size_t i = 0; i < filters_.size(); ++i) | 279 for (size_t i = 0; i < filters_.size(); ++i) |
276 filters_[i]->OnFilterAdded(channel_.get()); | 280 filters_[i]->OnFilterAdded(channel_.get()); |
(...skipping 26 matching lines...) Expand all Loading... |
303 } | 307 } |
304 | 308 |
305 bool ChildProcessHost::Send(IPC::Message* message) { | 309 bool ChildProcessHost::Send(IPC::Message* message) { |
306 if (!channel_.get()) { | 310 if (!channel_.get()) { |
307 delete message; | 311 delete message; |
308 return false; | 312 return false; |
309 } | 313 } |
310 return channel_->Send(message); | 314 return channel_->Send(message); |
311 } | 315 } |
312 | 316 |
| 317 void ChildProcessHost::OnAllocateSharedMemory( |
| 318 size_t buffer_size, base::ProcessHandle child_process_handle, |
| 319 base::SharedMemoryHandle* shared_memory_handle) { |
| 320 base::SharedMemory shared_buf; |
| 321 if (!shared_buf.CreateAndMapAnonymous(buffer_size)) { |
| 322 *shared_memory_handle = base::SharedMemory::NULLHandle(); |
| 323 NOTREACHED() << "Cannot map shared memory buffer"; |
| 324 return; |
| 325 } |
| 326 shared_buf.GiveToProcess(child_process_handle, shared_memory_handle); |
| 327 } |
| 328 |
313 void ChildProcessHost::OnChildDied() { | 329 void ChildProcessHost::OnChildDied() { |
314 delete this; | 330 delete this; |
315 } | 331 } |
316 | 332 |
317 void ChildProcessHost::OnChildDisconnected() { | 333 void ChildProcessHost::OnChildDisconnected() { |
318 OnChildDied(); | 334 OnChildDied(); |
319 } | 335 } |
320 | 336 |
321 void ChildProcessHost::ShutdownStarted() { | 337 void ChildProcessHost::ShutdownStarted() { |
322 } | 338 } |
323 | 339 |
324 void ChildProcessHost::Notify(int type) { | 340 void ChildProcessHost::Notify(int type) { |
325 } | 341 } |
326 | 342 |
327 ChildProcessHost::ListenerHook::ListenerHook(ChildProcessHost* host) | 343 ChildProcessHost::ListenerHook::ListenerHook(ChildProcessHost* host) |
328 : host_(host) { | 344 : host_(host), peer_handle_(base::kNullProcessHandle) { |
| 345 } |
| 346 |
| 347 ChildProcessHost::ListenerHook::~ListenerHook() { |
| 348 base::CloseProcessHandle(peer_handle_); |
329 } | 349 } |
330 | 350 |
331 void ChildProcessHost::ListenerHook::Shutdown() { | 351 void ChildProcessHost::ListenerHook::Shutdown() { |
332 host_ = NULL; | 352 host_ = NULL; |
333 } | 353 } |
334 | 354 |
335 bool ChildProcessHost::ListenerHook::OnMessageReceived( | 355 bool ChildProcessHost::ListenerHook::OnMessageReceived( |
336 const IPC::Message& msg) { | 356 const IPC::Message& msg) { |
337 if (!host_) | 357 if (!host_) |
338 return true; | 358 return true; |
(...skipping 10 matching lines...) Expand all Loading... |
349 #endif | 369 #endif |
350 | 370 |
351 bool handled = false; | 371 bool handled = false; |
352 for (size_t i = 0; i < host_->filters_.size(); ++i) { | 372 for (size_t i = 0; i < host_->filters_.size(); ++i) { |
353 if (host_->filters_[i]->OnMessageReceived(msg)) { | 373 if (host_->filters_[i]->OnMessageReceived(msg)) { |
354 handled = true; | 374 handled = true; |
355 break; | 375 break; |
356 } | 376 } |
357 } | 377 } |
358 | 378 |
359 if (!handled && msg.type() == ChildProcessHostMsg_ShutdownRequest::ID) { | 379 if (!handled) { |
360 if (host_->CanShutdown()) | 380 bool msg_is_good = false; |
361 host_->Send(new ChildProcessMsg_Shutdown()); | |
362 handled = true; | 381 handled = true; |
| 382 IPC_BEGIN_MESSAGE_MAP_EX(ListenerHook, msg, msg_is_good) |
| 383 IPC_MESSAGE_HANDLER(ChildProcessHostMsg_ShutdownRequest, |
| 384 OnShutdownRequest) |
| 385 IPC_MESSAGE_HANDLER(ChildProcessHostMsg_SyncAllocateSharedMemory, |
| 386 OnAllocateSharedMemory) |
| 387 IPC_MESSAGE_UNHANDLED(handled = false) |
| 388 IPC_END_MESSAGE_MAP_EX() |
| 389 |
| 390 if (!handled) |
| 391 handled = host_->OnMessageReceived(msg); |
363 } | 392 } |
364 | 393 |
365 if (!handled) | |
366 handled = host_->OnMessageReceived(msg); | |
367 | |
368 #ifdef IPC_MESSAGE_LOG_ENABLED | 394 #ifdef IPC_MESSAGE_LOG_ENABLED |
369 if (logger->Enabled()) | 395 if (logger->Enabled()) |
370 logger->OnPostDispatchMessage(msg, host_->channel_id_); | 396 logger->OnPostDispatchMessage(msg, host_->channel_id_); |
371 #endif | 397 #endif |
372 return handled; | 398 return handled; |
373 } | 399 } |
374 | 400 |
375 void ChildProcessHost::ListenerHook::OnChannelConnected(int32 peer_pid) { | 401 void ChildProcessHost::ListenerHook::OnChannelConnected(int32 peer_pid) { |
376 if (!host_) | 402 if (!host_) |
377 return; | 403 return; |
| 404 if (!base::OpenProcessHandle(peer_pid, &peer_handle_)) { |
| 405 NOTREACHED(); |
| 406 } |
378 host_->opening_channel_ = false; | 407 host_->opening_channel_ = false; |
379 host_->OnChannelConnected(peer_pid); | 408 host_->OnChannelConnected(peer_pid); |
380 // Notify in the main loop of the connection. | 409 // Notify in the main loop of the connection. |
381 host_->Notify(content::NOTIFICATION_CHILD_PROCESS_HOST_CONNECTED); | 410 host_->Notify(content::NOTIFICATION_CHILD_PROCESS_HOST_CONNECTED); |
382 | 411 |
383 for (size_t i = 0; i < host_->filters_.size(); ++i) | 412 for (size_t i = 0; i < host_->filters_.size(); ++i) |
384 host_->filters_[i]->OnChannelConnected(peer_pid); | 413 host_->filters_[i]->OnChannelConnected(peer_pid); |
385 } | 414 } |
386 | 415 |
387 void ChildProcessHost::ListenerHook::OnChannelError() { | 416 void ChildProcessHost::ListenerHook::OnChannelError() { |
388 if (!host_) | 417 if (!host_) |
389 return; | 418 return; |
390 host_->opening_channel_ = false; | 419 host_->opening_channel_ = false; |
391 host_->OnChannelError(); | 420 host_->OnChannelError(); |
392 | 421 |
393 for (size_t i = 0; i < host_->filters_.size(); ++i) | 422 for (size_t i = 0; i < host_->filters_.size(); ++i) |
394 host_->filters_[i]->OnChannelError(); | 423 host_->filters_[i]->OnChannelError(); |
395 | 424 |
396 // This will delete host_, which will also destroy this! | 425 // This will delete host_, which will also destroy this! |
397 host_->OnChildDisconnected(); | 426 host_->OnChildDisconnected(); |
398 } | 427 } |
399 | 428 |
400 void ChildProcessHost::ForceShutdown() { | 429 void ChildProcessHost::ListenerHook::OnAllocateSharedMemory( |
401 Send(new ChildProcessMsg_Shutdown()); | 430 size_t buffer_size, |
| 431 base::SharedMemoryHandle* handle) { |
| 432 ChildProcessHost::OnAllocateSharedMemory( |
| 433 buffer_size, peer_handle_, handle); |
402 } | 434 } |
| 435 |
| 436 void ChildProcessHost::ListenerHook::OnShutdownRequest() { |
| 437 if (host_->CanShutdown()) |
| 438 host_->Send(new ChildProcessMsg_Shutdown()); |
| 439 } |
OLD | NEW |