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 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
303 } | 304 } |
304 | 305 |
305 bool ChildProcessHost::Send(IPC::Message* message) { | 306 bool ChildProcessHost::Send(IPC::Message* message) { |
306 if (!channel_.get()) { | 307 if (!channel_.get()) { |
307 delete message; | 308 delete message; |
308 return false; | 309 return false; |
309 } | 310 } |
310 return channel_->Send(message); | 311 return channel_->Send(message); |
311 } | 312 } |
312 | 313 |
| 314 void ChildProcessHost::OnAllocateSharedMemory( |
| 315 size_t buffer_size, base::ProcessHandle child_process_handle, |
| 316 base::SharedMemoryHandle* shared_memory_handle) { |
| 317 base::SharedMemory shared_buf; |
| 318 if (!shared_buf.CreateAndMapAnonymous(buffer_size)) { |
| 319 *shared_memory_handle = base::SharedMemory::NULLHandle(); |
| 320 NOTREACHED() << "Cannot map shared memory buffer"; |
| 321 return; |
| 322 } |
| 323 shared_buf.GiveToProcess(child_process_handle, shared_memory_handle); |
| 324 } |
| 325 |
313 void ChildProcessHost::OnChildDied() { | 326 void ChildProcessHost::OnChildDied() { |
314 delete this; | 327 delete this; |
315 } | 328 } |
316 | 329 |
317 void ChildProcessHost::OnChildDisconnected() { | 330 void ChildProcessHost::OnChildDisconnected() { |
318 OnChildDied(); | 331 OnChildDied(); |
319 } | 332 } |
320 | 333 |
321 void ChildProcessHost::ShutdownStarted() { | 334 void ChildProcessHost::ShutdownStarted() { |
322 } | 335 } |
323 | 336 |
324 void ChildProcessHost::Notify(int type) { | 337 void ChildProcessHost::Notify(int type) { |
325 } | 338 } |
326 | 339 |
327 ChildProcessHost::ListenerHook::ListenerHook(ChildProcessHost* host) | 340 ChildProcessHost::ListenerHook::ListenerHook(ChildProcessHost* host) |
328 : host_(host) { | 341 : host_(host), peer_handle_(base::kNullProcessHandle) { |
| 342 } |
| 343 |
| 344 ChildProcessHost::ListenerHook::~ListenerHook() { |
| 345 base::CloseProcessHandle(peer_handle_); |
329 } | 346 } |
330 | 347 |
331 void ChildProcessHost::ListenerHook::Shutdown() { | 348 void ChildProcessHost::ListenerHook::Shutdown() { |
332 host_ = NULL; | 349 host_ = NULL; |
333 } | 350 } |
334 | 351 |
335 bool ChildProcessHost::ListenerHook::OnMessageReceived( | 352 bool ChildProcessHost::ListenerHook::OnMessageReceived( |
336 const IPC::Message& msg) { | 353 const IPC::Message& msg) { |
337 if (!host_) | 354 if (!host_) |
338 return true; | 355 return true; |
(...skipping 10 matching lines...) Expand all Loading... |
349 #endif | 366 #endif |
350 | 367 |
351 bool handled = false; | 368 bool handled = false; |
352 for (size_t i = 0; i < host_->filters_.size(); ++i) { | 369 for (size_t i = 0; i < host_->filters_.size(); ++i) { |
353 if (host_->filters_[i]->OnMessageReceived(msg)) { | 370 if (host_->filters_[i]->OnMessageReceived(msg)) { |
354 handled = true; | 371 handled = true; |
355 break; | 372 break; |
356 } | 373 } |
357 } | 374 } |
358 | 375 |
359 if (!handled && msg.type() == ChildProcessHostMsg_ShutdownRequest::ID) { | 376 if (!handled) { |
360 if (host_->CanShutdown()) | 377 bool msg_is_good = false; |
361 host_->Send(new ChildProcessMsg_Shutdown()); | |
362 handled = true; | 378 handled = true; |
| 379 IPC_BEGIN_MESSAGE_MAP_EX(ListenerHook, msg, msg_is_good) |
| 380 IPC_MESSAGE_HANDLER(ChildProcessHostMsg_ShutdownRequest, |
| 381 OnShutdownRequest) |
| 382 IPC_MESSAGE_HANDLER(ChildProcessHostMsg_SyncAllocateSharedMemory, |
| 383 OnAllocateSharedMemory) |
| 384 IPC_MESSAGE_UNHANDLED(handled = false) |
| 385 IPC_END_MESSAGE_MAP_EX() |
| 386 |
| 387 if (!handled) |
| 388 handled = host_->OnMessageReceived(msg); |
363 } | 389 } |
364 | 390 |
365 if (!handled) | |
366 handled = host_->OnMessageReceived(msg); | |
367 | |
368 #ifdef IPC_MESSAGE_LOG_ENABLED | 391 #ifdef IPC_MESSAGE_LOG_ENABLED |
369 if (logger->Enabled()) | 392 if (logger->Enabled()) |
370 logger->OnPostDispatchMessage(msg, host_->channel_id_); | 393 logger->OnPostDispatchMessage(msg, host_->channel_id_); |
371 #endif | 394 #endif |
372 return handled; | 395 return handled; |
373 } | 396 } |
374 | 397 |
375 void ChildProcessHost::ListenerHook::OnChannelConnected(int32 peer_pid) { | 398 void ChildProcessHost::ListenerHook::OnChannelConnected(int32 peer_pid) { |
376 if (!host_) | 399 if (!host_) |
377 return; | 400 return; |
| 401 if (!base::OpenProcessHandle(peer_pid, &peer_handle_)) { |
| 402 NOTREACHED(); |
| 403 } |
378 host_->opening_channel_ = false; | 404 host_->opening_channel_ = false; |
379 host_->OnChannelConnected(peer_pid); | 405 host_->OnChannelConnected(peer_pid); |
380 // Notify in the main loop of the connection. | 406 // Notify in the main loop of the connection. |
381 host_->Notify(content::NOTIFICATION_CHILD_PROCESS_HOST_CONNECTED); | 407 host_->Notify(content::NOTIFICATION_CHILD_PROCESS_HOST_CONNECTED); |
382 | 408 |
383 for (size_t i = 0; i < host_->filters_.size(); ++i) | 409 for (size_t i = 0; i < host_->filters_.size(); ++i) |
384 host_->filters_[i]->OnChannelConnected(peer_pid); | 410 host_->filters_[i]->OnChannelConnected(peer_pid); |
385 } | 411 } |
386 | 412 |
387 void ChildProcessHost::ListenerHook::OnChannelError() { | 413 void ChildProcessHost::ListenerHook::OnChannelError() { |
388 if (!host_) | 414 if (!host_) |
389 return; | 415 return; |
390 host_->opening_channel_ = false; | 416 host_->opening_channel_ = false; |
391 host_->OnChannelError(); | 417 host_->OnChannelError(); |
392 | 418 |
393 for (size_t i = 0; i < host_->filters_.size(); ++i) | 419 for (size_t i = 0; i < host_->filters_.size(); ++i) |
394 host_->filters_[i]->OnChannelError(); | 420 host_->filters_[i]->OnChannelError(); |
395 | 421 |
396 // This will delete host_, which will also destroy this! | 422 // This will delete host_, which will also destroy this! |
397 host_->OnChildDisconnected(); | 423 host_->OnChildDisconnected(); |
398 } | 424 } |
399 | 425 |
| 426 void ChildProcessHost::ListenerHook::OnAllocateSharedMemory( |
| 427 size_t buffer_size, |
| 428 base::SharedMemoryHandle* handle) { |
| 429 ChildProcessHost::OnAllocateSharedMemory( |
| 430 buffer_size, peer_handle_, handle); |
| 431 } |
| 432 |
| 433 void ChildProcessHost::ListenerHook::OnShutdownRequest() { |
| 434 if (host_->CanShutdown()) |
| 435 host_->Send(new ChildProcessMsg_Shutdown()); |
| 436 } |
| 437 |
400 void ChildProcessHost::ForceShutdown() { | 438 void ChildProcessHost::ForceShutdown() { |
401 Send(new ChildProcessMsg_Shutdown()); | 439 Send(new ChildProcessMsg_Shutdown()); |
402 } | 440 } |
OLD | NEW |