| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/child/child_thread.h" | 5 #include "content/child/child_thread_impl.h" |
| 6 | 6 |
| 7 #include <signal.h> | 7 #include <signal.h> |
| 8 | 8 |
| 9 #include <string> | 9 #include <string> |
| 10 | 10 |
| 11 #include "base/allocator/allocator_extension.h" | 11 #include "base/allocator/allocator_extension.h" |
| 12 #include "base/base_switches.h" | 12 #include "base/base_switches.h" |
| 13 #include "base/basictypes.h" | 13 #include "base/basictypes.h" |
| 14 #include "base/command_line.h" | 14 #include "base/command_line.h" |
| 15 #include "base/debug/leak_annotations.h" | 15 #include "base/debug/leak_annotations.h" |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 64 #endif | 64 #endif |
| 65 | 65 |
| 66 using tracked_objects::ThreadData; | 66 using tracked_objects::ThreadData; |
| 67 | 67 |
| 68 namespace content { | 68 namespace content { |
| 69 namespace { | 69 namespace { |
| 70 | 70 |
| 71 // How long to wait for a connection to the browser process before giving up. | 71 // How long to wait for a connection to the browser process before giving up. |
| 72 const int kConnectionTimeoutS = 15; | 72 const int kConnectionTimeoutS = 15; |
| 73 | 73 |
| 74 base::LazyInstance<base::ThreadLocalPointer<ChildThread> > g_lazy_tls = | 74 base::LazyInstance<base::ThreadLocalPointer<ChildThreadImpl> > g_lazy_tls = |
| 75 LAZY_INSTANCE_INITIALIZER; | 75 LAZY_INSTANCE_INITIALIZER; |
| 76 | 76 |
| 77 // This isn't needed on Windows because there the sandbox's job object | 77 // This isn't needed on Windows because there the sandbox's job object |
| 78 // terminates child processes automatically. For unsandboxed processes (i.e. | 78 // terminates child processes automatically. For unsandboxed processes (i.e. |
| 79 // plugins), PluginThread has EnsureTerminateMessageFilter. | 79 // plugins), PluginThread has EnsureTerminateMessageFilter. |
| 80 #if defined(OS_POSIX) | 80 #if defined(OS_POSIX) |
| 81 | 81 |
| 82 // TODO(earthdok): Re-enable on CrOS http://crbug.com/360622 | 82 // TODO(earthdok): Re-enable on CrOS http://crbug.com/360622 |
| 83 #if (defined(ADDRESS_SANITIZER) || defined(LEAK_SANITIZER) || \ | 83 #if (defined(ADDRESS_SANITIZER) || defined(LEAK_SANITIZER) || \ |
| 84 defined(MEMORY_SANITIZER) || defined(THREAD_SANITIZER) || \ | 84 defined(MEMORY_SANITIZER) || defined(THREAD_SANITIZER) || \ |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 155 #endif | 155 #endif |
| 156 } | 156 } |
| 157 | 157 |
| 158 protected: | 158 protected: |
| 159 ~SuicideOnChannelErrorFilter() override {} | 159 ~SuicideOnChannelErrorFilter() override {} |
| 160 }; | 160 }; |
| 161 | 161 |
| 162 #endif // OS(POSIX) | 162 #endif // OS(POSIX) |
| 163 | 163 |
| 164 #if defined(OS_ANDROID) | 164 #if defined(OS_ANDROID) |
| 165 ChildThread* g_child_thread = NULL; | 165 ChildThreadImpl* g_child_thread = NULL; |
| 166 | 166 |
| 167 // A lock protects g_child_thread. | 167 // A lock protects g_child_thread. |
| 168 base::LazyInstance<base::Lock> g_lazy_child_thread_lock = | 168 base::LazyInstance<base::Lock> g_lazy_child_thread_lock = |
| 169 LAZY_INSTANCE_INITIALIZER; | 169 LAZY_INSTANCE_INITIALIZER; |
| 170 | 170 |
| 171 // base::ConditionVariable has an explicit constructor that takes | 171 // base::ConditionVariable has an explicit constructor that takes |
| 172 // a base::Lock pointer as parameter. The base::DefaultLazyInstanceTraits | 172 // a base::Lock pointer as parameter. The base::DefaultLazyInstanceTraits |
| 173 // doesn't handle the case. Thus, we need our own class here. | 173 // doesn't handle the case. Thus, we need our own class here. |
| 174 struct CondVarLazyInstanceTraits { | 174 struct CondVarLazyInstanceTraits { |
| 175 static const bool kRegisterOnExit = true; | 175 static const bool kRegisterOnExit = true; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 192 g_lazy_child_thread_cv = LAZY_INSTANCE_INITIALIZER; | 192 g_lazy_child_thread_cv = LAZY_INSTANCE_INITIALIZER; |
| 193 | 193 |
| 194 void QuitMainThreadMessageLoop() { | 194 void QuitMainThreadMessageLoop() { |
| 195 base::MessageLoop::current()->Quit(); | 195 base::MessageLoop::current()->Quit(); |
| 196 } | 196 } |
| 197 | 197 |
| 198 #endif | 198 #endif |
| 199 | 199 |
| 200 } // namespace | 200 } // namespace |
| 201 | 201 |
| 202 ChildThread::Options::Options() | 202 ChildThread* ChildThread::Get() { |
| 203 return ChildThreadImpl::current(); |
| 204 } |
| 205 |
| 206 ChildThreadImpl::Options::Options() |
| 203 : channel_name(base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( | 207 : channel_name(base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |
| 204 switches::kProcessChannelID)), | 208 switches::kProcessChannelID)), |
| 205 use_mojo_channel(false), | 209 use_mojo_channel(false), |
| 206 in_browser_process(false) { | 210 in_browser_process(false) { |
| 207 } | 211 } |
| 208 | 212 |
| 209 ChildThread::Options::Options(bool mojo) | 213 ChildThreadImpl::Options::Options(bool mojo) |
| 210 : channel_name(base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( | 214 : channel_name(base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |
| 211 switches::kProcessChannelID)), | 215 switches::kProcessChannelID)), |
| 212 use_mojo_channel(mojo), | 216 use_mojo_channel(mojo), |
| 213 in_browser_process(true) { | 217 in_browser_process(true) { |
| 214 } | 218 } |
| 215 | 219 |
| 216 ChildThread::Options::Options(std::string name, bool mojo) | 220 ChildThreadImpl::Options::Options(std::string name, bool mojo) |
| 217 : channel_name(name), use_mojo_channel(mojo), in_browser_process(true) { | 221 : channel_name(name), use_mojo_channel(mojo), in_browser_process(true) { |
| 218 } | 222 } |
| 219 | 223 |
| 220 ChildThread::Options::~Options() { | 224 ChildThreadImpl::Options::~Options() { |
| 221 } | 225 } |
| 222 | 226 |
| 223 ChildThread::ChildThreadMessageRouter::ChildThreadMessageRouter( | 227 ChildThreadImpl::ChildThreadMessageRouter::ChildThreadMessageRouter( |
| 224 IPC::Sender* sender) | 228 IPC::Sender* sender) |
| 225 : sender_(sender) {} | 229 : sender_(sender) {} |
| 226 | 230 |
| 227 bool ChildThread::ChildThreadMessageRouter::Send(IPC::Message* msg) { | 231 bool ChildThreadImpl::ChildThreadMessageRouter::Send(IPC::Message* msg) { |
| 228 return sender_->Send(msg); | 232 return sender_->Send(msg); |
| 229 } | 233 } |
| 230 | 234 |
| 231 ChildThread::ChildThread() | 235 ChildThreadImpl::ChildThreadImpl() |
| 232 : router_(this), | 236 : router_(this), |
| 233 in_browser_process_(false), | 237 in_browser_process_(false), |
| 234 channel_connected_factory_(this) { | 238 channel_connected_factory_(this) { |
| 235 Init(Options()); | 239 Init(Options()); |
| 236 } | 240 } |
| 237 | 241 |
| 238 ChildThread::ChildThread(const Options& options) | 242 ChildThreadImpl::ChildThreadImpl(const Options& options) |
| 239 : router_(this), | 243 : router_(this), |
| 240 in_browser_process_(options.in_browser_process), | 244 in_browser_process_(options.in_browser_process), |
| 241 channel_connected_factory_(this) { | 245 channel_connected_factory_(this) { |
| 242 Init(options); | 246 Init(options); |
| 243 } | 247 } |
| 244 | 248 |
| 245 void ChildThread::ConnectChannel(bool use_mojo_channel) { | 249 void ChildThreadImpl::ConnectChannel(bool use_mojo_channel) { |
| 246 bool create_pipe_now = true; | 250 bool create_pipe_now = true; |
| 247 if (use_mojo_channel) { | 251 if (use_mojo_channel) { |
| 248 VLOG(1) << "Mojo is enabled on child"; | 252 VLOG(1) << "Mojo is enabled on child"; |
| 249 channel_->Init(IPC::ChannelMojo::CreateClientFactory(channel_name_), | 253 channel_->Init(IPC::ChannelMojo::CreateClientFactory(channel_name_), |
| 250 create_pipe_now); | 254 create_pipe_now); |
| 251 return; | 255 return; |
| 252 } | 256 } |
| 253 | 257 |
| 254 VLOG(1) << "Mojo is disabled on child"; | 258 VLOG(1) << "Mojo is disabled on child"; |
| 255 channel_->Init(channel_name_, IPC::Channel::MODE_CLIENT, create_pipe_now); | 259 channel_->Init(channel_name_, IPC::Channel::MODE_CLIENT, create_pipe_now); |
| 256 } | 260 } |
| 257 | 261 |
| 258 void ChildThread::Init(const Options& options) { | 262 void ChildThreadImpl::Init(const Options& options) { |
| 259 channel_name_ = options.channel_name; | 263 channel_name_ = options.channel_name; |
| 260 | 264 |
| 261 g_lazy_tls.Pointer()->Set(this); | 265 g_lazy_tls.Pointer()->Set(this); |
| 262 on_channel_error_called_ = false; | 266 on_channel_error_called_ = false; |
| 263 message_loop_ = base::MessageLoop::current(); | 267 message_loop_ = base::MessageLoop::current(); |
| 264 #ifdef IPC_MESSAGE_LOG_ENABLED | 268 #ifdef IPC_MESSAGE_LOG_ENABLED |
| 265 // We must make sure to instantiate the IPC Logger *before* we create the | 269 // We must make sure to instantiate the IPC Logger *before* we create the |
| 266 // channel, otherwise we can get a callback on the IO thread which creates | 270 // channel, otherwise we can get a callback on the IO thread which creates |
| 267 // the logger, and the logger does not like being created on the IO thread. | 271 // the logger, and the logger does not like being created on the IO thread. |
| 268 IPC::Logging::GetInstance(); | 272 IPC::Logging::GetInstance(); |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 356 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( | 360 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |
| 357 switches::kIPCConnectionTimeout); | 361 switches::kIPCConnectionTimeout); |
| 358 if (!connection_override.empty()) { | 362 if (!connection_override.empty()) { |
| 359 int temp; | 363 int temp; |
| 360 if (base::StringToInt(connection_override, &temp)) | 364 if (base::StringToInt(connection_override, &temp)) |
| 361 connection_timeout = temp; | 365 connection_timeout = temp; |
| 362 } | 366 } |
| 363 | 367 |
| 364 base::MessageLoop::current()->PostDelayedTask( | 368 base::MessageLoop::current()->PostDelayedTask( |
| 365 FROM_HERE, | 369 FROM_HERE, |
| 366 base::Bind(&ChildThread::EnsureConnected, | 370 base::Bind(&ChildThreadImpl::EnsureConnected, |
| 367 channel_connected_factory_.GetWeakPtr()), | 371 channel_connected_factory_.GetWeakPtr()), |
| 368 base::TimeDelta::FromSeconds(connection_timeout)); | 372 base::TimeDelta::FromSeconds(connection_timeout)); |
| 369 | 373 |
| 370 #if defined(OS_ANDROID) | 374 #if defined(OS_ANDROID) |
| 371 { | 375 { |
| 372 base::AutoLock lock(g_lazy_child_thread_lock.Get()); | 376 base::AutoLock lock(g_lazy_child_thread_lock.Get()); |
| 373 g_child_thread = this; | 377 g_child_thread = this; |
| 374 } | 378 } |
| 375 // Signalling without locking is fine here because only | 379 // Signalling without locking is fine here because only |
| 376 // one thread can wait on the condition variable. | 380 // one thread can wait on the condition variable. |
| (...skipping 11 matching lines...) Expand all Loading... |
| 388 shared_bitmap_manager_.reset( | 392 shared_bitmap_manager_.reset( |
| 389 new ChildSharedBitmapManager(thread_safe_sender())); | 393 new ChildSharedBitmapManager(thread_safe_sender())); |
| 390 | 394 |
| 391 gpu_memory_buffer_manager_.reset( | 395 gpu_memory_buffer_manager_.reset( |
| 392 new ChildGpuMemoryBufferManager(thread_safe_sender())); | 396 new ChildGpuMemoryBufferManager(thread_safe_sender())); |
| 393 | 397 |
| 394 discardable_shared_memory_manager_.reset( | 398 discardable_shared_memory_manager_.reset( |
| 395 new ChildDiscardableSharedMemoryManager(thread_safe_sender())); | 399 new ChildDiscardableSharedMemoryManager(thread_safe_sender())); |
| 396 } | 400 } |
| 397 | 401 |
| 398 ChildThread::~ChildThread() { | 402 ChildThreadImpl::~ChildThreadImpl() { |
| 399 #ifdef IPC_MESSAGE_LOG_ENABLED | 403 #ifdef IPC_MESSAGE_LOG_ENABLED |
| 400 IPC::Logging::GetInstance()->SetIPCSender(NULL); | 404 IPC::Logging::GetInstance()->SetIPCSender(NULL); |
| 401 #endif | 405 #endif |
| 402 | 406 |
| 403 channel_->RemoveFilter(histogram_message_filter_.get()); | 407 channel_->RemoveFilter(histogram_message_filter_.get()); |
| 404 channel_->RemoveFilter(sync_message_filter_.get()); | 408 channel_->RemoveFilter(sync_message_filter_.get()); |
| 405 | 409 |
| 406 // The ChannelProxy object caches a pointer to the IPC thread, so need to | 410 // The ChannelProxy object caches a pointer to the IPC thread, so need to |
| 407 // reset it as it's not guaranteed to outlive this object. | 411 // reset it as it's not guaranteed to outlive this object. |
| 408 // NOTE: this also has the side-effect of not closing the main IPC channel to | 412 // NOTE: this also has the side-effect of not closing the main IPC channel to |
| 409 // the browser process. This is needed because this is the signal that the | 413 // the browser process. This is needed because this is the signal that the |
| 410 // browser uses to know that this process has died, so we need it to be alive | 414 // browser uses to know that this process has died, so we need it to be alive |
| 411 // until this process is shut down, and the OS closes the handle | 415 // until this process is shut down, and the OS closes the handle |
| 412 // automatically. We used to watch the object handle on Windows to do this, | 416 // automatically. We used to watch the object handle on Windows to do this, |
| 413 // but it wasn't possible to do so on POSIX. | 417 // but it wasn't possible to do so on POSIX. |
| 414 channel_->ClearIPCTaskRunner(); | 418 channel_->ClearIPCTaskRunner(); |
| 415 g_lazy_tls.Pointer()->Set(NULL); | 419 g_lazy_tls.Pointer()->Set(NULL); |
| 416 } | 420 } |
| 417 | 421 |
| 418 void ChildThread::Shutdown() { | 422 void ChildThreadImpl::Shutdown() { |
| 419 // Delete objects that hold references to blink so derived classes can | 423 // Delete objects that hold references to blink so derived classes can |
| 420 // safely shutdown blink in their Shutdown implementation. | 424 // safely shutdown blink in their Shutdown implementation. |
| 421 file_system_dispatcher_.reset(); | 425 file_system_dispatcher_.reset(); |
| 422 quota_dispatcher_.reset(); | 426 quota_dispatcher_.reset(); |
| 423 WebFileSystemImpl::DeleteThreadSpecificInstance(); | 427 WebFileSystemImpl::DeleteThreadSpecificInstance(); |
| 424 } | 428 } |
| 425 | 429 |
| 426 void ChildThread::OnChannelConnected(int32 peer_pid) { | 430 void ChildThreadImpl::OnChannelConnected(int32 peer_pid) { |
| 427 channel_connected_factory_.InvalidateWeakPtrs(); | 431 channel_connected_factory_.InvalidateWeakPtrs(); |
| 428 } | 432 } |
| 429 | 433 |
| 430 void ChildThread::OnChannelError() { | 434 void ChildThreadImpl::OnChannelError() { |
| 431 set_on_channel_error_called(true); | 435 set_on_channel_error_called(true); |
| 432 base::MessageLoop::current()->Quit(); | 436 base::MessageLoop::current()->Quit(); |
| 433 } | 437 } |
| 434 | 438 |
| 435 bool ChildThread::Send(IPC::Message* msg) { | 439 bool ChildThreadImpl::Send(IPC::Message* msg) { |
| 436 DCHECK(base::MessageLoop::current() == message_loop()); | 440 DCHECK(base::MessageLoop::current() == message_loop()); |
| 437 if (!channel_) { | 441 if (!channel_) { |
| 438 delete msg; | 442 delete msg; |
| 439 return false; | 443 return false; |
| 440 } | 444 } |
| 441 | 445 |
| 442 return channel_->Send(msg); | 446 return channel_->Send(msg); |
| 443 } | 447 } |
| 444 | 448 |
| 445 MessageRouter* ChildThread::GetRouter() { | 449 #if defined(OS_WIN) |
| 450 void ChildThreadImpl::PreCacheFont(const LOGFONT& log_font) { |
| 451 Send(new ChildProcessHostMsg_PreCacheFont(log_font)); |
| 452 } |
| 453 |
| 454 void ChildThreadImpl::ReleaseCachedFonts() { |
| 455 Send(new ChildProcessHostMsg_ReleaseCachedFonts()); |
| 456 } |
| 457 #endif |
| 458 |
| 459 MessageRouter* ChildThreadImpl::GetRouter() { |
| 446 DCHECK(base::MessageLoop::current() == message_loop()); | 460 DCHECK(base::MessageLoop::current() == message_loop()); |
| 447 return &router_; | 461 return &router_; |
| 448 } | 462 } |
| 449 | 463 |
| 450 scoped_ptr<base::SharedMemory> ChildThread::AllocateSharedMemory( | 464 scoped_ptr<base::SharedMemory> ChildThreadImpl::AllocateSharedMemory( |
| 451 size_t buf_size) { | 465 size_t buf_size) { |
| 452 DCHECK(base::MessageLoop::current() == message_loop()); | 466 DCHECK(base::MessageLoop::current() == message_loop()); |
| 453 return AllocateSharedMemory(buf_size, this); | 467 return AllocateSharedMemory(buf_size, this); |
| 454 } | 468 } |
| 455 | 469 |
| 456 // static | 470 // static |
| 457 scoped_ptr<base::SharedMemory> ChildThread::AllocateSharedMemory( | 471 scoped_ptr<base::SharedMemory> ChildThreadImpl::AllocateSharedMemory( |
| 458 size_t buf_size, | 472 size_t buf_size, |
| 459 IPC::Sender* sender) { | 473 IPC::Sender* sender) { |
| 460 scoped_ptr<base::SharedMemory> shared_buf; | 474 scoped_ptr<base::SharedMemory> shared_buf; |
| 461 #if defined(OS_WIN) | 475 #if defined(OS_WIN) |
| 462 shared_buf.reset(new base::SharedMemory); | 476 shared_buf.reset(new base::SharedMemory); |
| 463 if (!shared_buf->CreateAnonymous(buf_size)) { | 477 if (!shared_buf->CreateAnonymous(buf_size)) { |
| 464 NOTREACHED(); | 478 NOTREACHED(); |
| 465 return NULL; | 479 return NULL; |
| 466 } | 480 } |
| 467 #else | 481 #else |
| 468 // On POSIX, we need to ask the browser to create the shared memory for us, | 482 // On POSIX, we need to ask the browser to create the shared memory for us, |
| 469 // since this is blocked by the sandbox. | 483 // since this is blocked by the sandbox. |
| 470 base::SharedMemoryHandle shared_mem_handle; | 484 base::SharedMemoryHandle shared_mem_handle; |
| 471 if (sender->Send(new ChildProcessHostMsg_SyncAllocateSharedMemory( | 485 if (sender->Send(new ChildProcessHostMsg_SyncAllocateSharedMemory( |
| 472 buf_size, &shared_mem_handle))) { | 486 buf_size, &shared_mem_handle))) { |
| 473 if (base::SharedMemory::IsHandleValid(shared_mem_handle)) { | 487 if (base::SharedMemory::IsHandleValid(shared_mem_handle)) { |
| 474 shared_buf.reset(new base::SharedMemory(shared_mem_handle, false)); | 488 shared_buf.reset(new base::SharedMemory(shared_mem_handle, false)); |
| 475 } else { | 489 } else { |
| 476 NOTREACHED() << "Browser failed to allocate shared memory"; | 490 NOTREACHED() << "Browser failed to allocate shared memory"; |
| 477 return NULL; | 491 return NULL; |
| 478 } | 492 } |
| 479 } else { | 493 } else { |
| 480 NOTREACHED() << "Browser allocation request message failed"; | 494 NOTREACHED() << "Browser allocation request message failed"; |
| 481 return NULL; | 495 return NULL; |
| 482 } | 496 } |
| 483 #endif | 497 #endif |
| 484 return shared_buf; | 498 return shared_buf; |
| 485 } | 499 } |
| 486 | 500 |
| 487 bool ChildThread::OnMessageReceived(const IPC::Message& msg) { | 501 bool ChildThreadImpl::OnMessageReceived(const IPC::Message& msg) { |
| 488 if (mojo_application_->OnMessageReceived(msg)) | 502 if (mojo_application_->OnMessageReceived(msg)) |
| 489 return true; | 503 return true; |
| 490 | 504 |
| 491 // Resource responses are sent to the resource dispatcher. | 505 // Resource responses are sent to the resource dispatcher. |
| 492 if (resource_dispatcher_->OnMessageReceived(msg)) | 506 if (resource_dispatcher_->OnMessageReceived(msg)) |
| 493 return true; | 507 return true; |
| 494 if (websocket_dispatcher_->OnMessageReceived(msg)) | 508 if (websocket_dispatcher_->OnMessageReceived(msg)) |
| 495 return true; | 509 return true; |
| 496 if (file_system_dispatcher_->OnMessageReceived(msg)) | 510 if (file_system_dispatcher_->OnMessageReceived(msg)) |
| 497 return true; | 511 return true; |
| 498 | 512 |
| 499 bool handled = true; | 513 bool handled = true; |
| 500 IPC_BEGIN_MESSAGE_MAP(ChildThread, msg) | 514 IPC_BEGIN_MESSAGE_MAP(ChildThreadImpl, msg) |
| 501 IPC_MESSAGE_HANDLER(ChildProcessMsg_Shutdown, OnShutdown) | 515 IPC_MESSAGE_HANDLER(ChildProcessMsg_Shutdown, OnShutdown) |
| 502 #if defined(IPC_MESSAGE_LOG_ENABLED) | 516 #if defined(IPC_MESSAGE_LOG_ENABLED) |
| 503 IPC_MESSAGE_HANDLER(ChildProcessMsg_SetIPCLoggingEnabled, | 517 IPC_MESSAGE_HANDLER(ChildProcessMsg_SetIPCLoggingEnabled, |
| 504 OnSetIPCLoggingEnabled) | 518 OnSetIPCLoggingEnabled) |
| 505 #endif | 519 #endif |
| 506 IPC_MESSAGE_HANDLER(ChildProcessMsg_SetProfilerStatus, | 520 IPC_MESSAGE_HANDLER(ChildProcessMsg_SetProfilerStatus, |
| 507 OnSetProfilerStatus) | 521 OnSetProfilerStatus) |
| 508 IPC_MESSAGE_HANDLER(ChildProcessMsg_GetChildProfilerData, | 522 IPC_MESSAGE_HANDLER(ChildProcessMsg_GetChildProfilerData, |
| 509 OnGetChildProfilerData) | 523 OnGetChildProfilerData) |
| 510 IPC_MESSAGE_HANDLER(ChildProcessMsg_DumpHandles, OnDumpHandles) | 524 IPC_MESSAGE_HANDLER(ChildProcessMsg_DumpHandles, OnDumpHandles) |
| 511 IPC_MESSAGE_HANDLER(ChildProcessMsg_SetProcessBackgrounded, | 525 IPC_MESSAGE_HANDLER(ChildProcessMsg_SetProcessBackgrounded, |
| 512 OnProcessBackgrounded) | 526 OnProcessBackgrounded) |
| 513 #if defined(USE_TCMALLOC) | 527 #if defined(USE_TCMALLOC) |
| 514 IPC_MESSAGE_HANDLER(ChildProcessMsg_GetTcmallocStats, OnGetTcmallocStats) | 528 IPC_MESSAGE_HANDLER(ChildProcessMsg_GetTcmallocStats, OnGetTcmallocStats) |
| 515 #endif | 529 #endif |
| 516 IPC_MESSAGE_UNHANDLED(handled = false) | 530 IPC_MESSAGE_UNHANDLED(handled = false) |
| 517 IPC_END_MESSAGE_MAP() | 531 IPC_END_MESSAGE_MAP() |
| 518 | 532 |
| 519 if (handled) | 533 if (handled) |
| 520 return true; | 534 return true; |
| 521 | 535 |
| 522 if (msg.routing_id() == MSG_ROUTING_CONTROL) | 536 if (msg.routing_id() == MSG_ROUTING_CONTROL) |
| 523 return OnControlMessageReceived(msg); | 537 return OnControlMessageReceived(msg); |
| 524 | 538 |
| 525 return router_.OnMessageReceived(msg); | 539 return router_.OnMessageReceived(msg); |
| 526 } | 540 } |
| 527 | 541 |
| 528 bool ChildThread::OnControlMessageReceived(const IPC::Message& msg) { | 542 bool ChildThreadImpl::OnControlMessageReceived(const IPC::Message& msg) { |
| 529 return false; | 543 return false; |
| 530 } | 544 } |
| 531 | 545 |
| 532 void ChildThread::OnShutdown() { | 546 void ChildThreadImpl::OnShutdown() { |
| 533 base::MessageLoop::current()->Quit(); | 547 base::MessageLoop::current()->Quit(); |
| 534 } | 548 } |
| 535 | 549 |
| 536 #if defined(IPC_MESSAGE_LOG_ENABLED) | 550 #if defined(IPC_MESSAGE_LOG_ENABLED) |
| 537 void ChildThread::OnSetIPCLoggingEnabled(bool enable) { | 551 void ChildThreadImpl::OnSetIPCLoggingEnabled(bool enable) { |
| 538 if (enable) | 552 if (enable) |
| 539 IPC::Logging::GetInstance()->Enable(); | 553 IPC::Logging::GetInstance()->Enable(); |
| 540 else | 554 else |
| 541 IPC::Logging::GetInstance()->Disable(); | 555 IPC::Logging::GetInstance()->Disable(); |
| 542 } | 556 } |
| 543 #endif // IPC_MESSAGE_LOG_ENABLED | 557 #endif // IPC_MESSAGE_LOG_ENABLED |
| 544 | 558 |
| 545 void ChildThread::OnSetProfilerStatus(ThreadData::Status status) { | 559 void ChildThreadImpl::OnSetProfilerStatus(ThreadData::Status status) { |
| 546 ThreadData::InitializeAndSetTrackingStatus(status); | 560 ThreadData::InitializeAndSetTrackingStatus(status); |
| 547 } | 561 } |
| 548 | 562 |
| 549 void ChildThread::OnGetChildProfilerData(int sequence_number) { | 563 void ChildThreadImpl::OnGetChildProfilerData(int sequence_number) { |
| 550 tracked_objects::ProcessDataSnapshot process_data; | 564 tracked_objects::ProcessDataSnapshot process_data; |
| 551 ThreadData::Snapshot(false, &process_data); | 565 ThreadData::Snapshot(false, &process_data); |
| 552 | 566 |
| 553 Send(new ChildProcessHostMsg_ChildProfilerData(sequence_number, | 567 Send(new ChildProcessHostMsg_ChildProfilerData(sequence_number, |
| 554 process_data)); | 568 process_data)); |
| 555 } | 569 } |
| 556 | 570 |
| 557 void ChildThread::OnDumpHandles() { | 571 void ChildThreadImpl::OnDumpHandles() { |
| 558 #if defined(OS_WIN) | 572 #if defined(OS_WIN) |
| 559 scoped_refptr<HandleEnumerator> handle_enum( | 573 scoped_refptr<HandleEnumerator> handle_enum( |
| 560 new HandleEnumerator( | 574 new HandleEnumerator( |
| 561 base::CommandLine::ForCurrentProcess()->HasSwitch( | 575 base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 562 switches::kAuditAllHandles))); | 576 switches::kAuditAllHandles))); |
| 563 handle_enum->EnumerateHandles(); | 577 handle_enum->EnumerateHandles(); |
| 564 Send(new ChildProcessHostMsg_DumpHandlesDone); | 578 Send(new ChildProcessHostMsg_DumpHandlesDone); |
| 565 #else | 579 #else |
| 566 NOTIMPLEMENTED(); | 580 NOTIMPLEMENTED(); |
| 567 #endif | 581 #endif |
| 568 } | 582 } |
| 569 | 583 |
| 570 #if defined(USE_TCMALLOC) | 584 #if defined(USE_TCMALLOC) |
| 571 void ChildThread::OnGetTcmallocStats() { | 585 void ChildThreadImpl::OnGetTcmallocStats() { |
| 572 std::string result; | 586 std::string result; |
| 573 char buffer[1024 * 32]; | 587 char buffer[1024 * 32]; |
| 574 base::allocator::GetStats(buffer, sizeof(buffer)); | 588 base::allocator::GetStats(buffer, sizeof(buffer)); |
| 575 result.append(buffer); | 589 result.append(buffer); |
| 576 Send(new ChildProcessHostMsg_TcmallocStats(result)); | 590 Send(new ChildProcessHostMsg_TcmallocStats(result)); |
| 577 } | 591 } |
| 578 #endif | 592 #endif |
| 579 | 593 |
| 580 ChildThread* ChildThread::current() { | 594 ChildThreadImpl* ChildThreadImpl::current() { |
| 581 return g_lazy_tls.Pointer()->Get(); | 595 return g_lazy_tls.Pointer()->Get(); |
| 582 } | 596 } |
| 583 | 597 |
| 584 #if defined(OS_ANDROID) | 598 #if defined(OS_ANDROID) |
| 585 // The method must NOT be called on the child thread itself. | 599 // The method must NOT be called on the child thread itself. |
| 586 // It may block the child thread if so. | 600 // It may block the child thread if so. |
| 587 void ChildThread::ShutdownThread() { | 601 void ChildThreadImpl::ShutdownThread() { |
| 588 DCHECK(!ChildThread::current()) << | 602 DCHECK(!ChildThreadImpl::current()) << |
| 589 "this method should NOT be called from child thread itself"; | 603 "this method should NOT be called from child thread itself"; |
| 590 { | 604 { |
| 591 base::AutoLock lock(g_lazy_child_thread_lock.Get()); | 605 base::AutoLock lock(g_lazy_child_thread_lock.Get()); |
| 592 while (!g_child_thread) | 606 while (!g_child_thread) |
| 593 g_lazy_child_thread_cv.Get().Wait(); | 607 g_lazy_child_thread_cv.Get().Wait(); |
| 594 } | 608 } |
| 595 DCHECK_NE(base::MessageLoop::current(), g_child_thread->message_loop()); | 609 DCHECK_NE(base::MessageLoop::current(), g_child_thread->message_loop()); |
| 596 g_child_thread->message_loop()->PostTask( | 610 g_child_thread->message_loop()->PostTask( |
| 597 FROM_HERE, base::Bind(&QuitMainThreadMessageLoop)); | 611 FROM_HERE, base::Bind(&QuitMainThreadMessageLoop)); |
| 598 } | 612 } |
| 599 #endif | 613 #endif |
| 600 | 614 |
| 601 void ChildThread::OnProcessFinalRelease() { | 615 void ChildThreadImpl::OnProcessFinalRelease() { |
| 602 if (on_channel_error_called_) { | 616 if (on_channel_error_called_) { |
| 603 base::MessageLoop::current()->Quit(); | 617 base::MessageLoop::current()->Quit(); |
| 604 return; | 618 return; |
| 605 } | 619 } |
| 606 | 620 |
| 607 // The child process shutdown sequence is a request response based mechanism, | 621 // The child process shutdown sequence is a request response based mechanism, |
| 608 // where we send out an initial feeler request to the child process host | 622 // where we send out an initial feeler request to the child process host |
| 609 // instance in the browser to verify if it's ok to shutdown the child process. | 623 // instance in the browser to verify if it's ok to shutdown the child process. |
| 610 // The browser then sends back a response if it's ok to shutdown. This avoids | 624 // The browser then sends back a response if it's ok to shutdown. This avoids |
| 611 // race conditions if the process refcount is 0 but there's an IPC message | 625 // race conditions if the process refcount is 0 but there's an IPC message |
| 612 // inflight that would addref it. | 626 // inflight that would addref it. |
| 613 Send(new ChildProcessHostMsg_ShutdownRequest); | 627 Send(new ChildProcessHostMsg_ShutdownRequest); |
| 614 } | 628 } |
| 615 | 629 |
| 616 void ChildThread::EnsureConnected() { | 630 void ChildThreadImpl::EnsureConnected() { |
| 617 VLOG(0) << "ChildThread::EnsureConnected()"; | 631 VLOG(0) << "ChildThreadImpl::EnsureConnected()"; |
| 618 base::KillProcess(base::GetCurrentProcessHandle(), 0, false); | 632 base::KillProcess(base::GetCurrentProcessHandle(), 0, false); |
| 619 } | 633 } |
| 620 | 634 |
| 621 void ChildThread::OnProcessBackgrounded(bool background) { | 635 void ChildThreadImpl::OnProcessBackgrounded(bool background) { |
| 622 // Set timer slack to maximum on main thread when in background. | 636 // Set timer slack to maximum on main thread when in background. |
| 623 base::TimerSlack timer_slack = base::TIMER_SLACK_NONE; | 637 base::TimerSlack timer_slack = base::TIMER_SLACK_NONE; |
| 624 if (background) | 638 if (background) |
| 625 timer_slack = base::TIMER_SLACK_MAXIMUM; | 639 timer_slack = base::TIMER_SLACK_MAXIMUM; |
| 626 base::MessageLoop::current()->SetTimerSlack(timer_slack); | 640 base::MessageLoop::current()->SetTimerSlack(timer_slack); |
| 627 } | 641 } |
| 628 | 642 |
| 629 } // namespace content | 643 } // namespace content |
| OLD | NEW |