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 |