| 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.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/allocator/allocator_extension.h" | 9 #include "base/allocator/allocator_extension.h" |
| 10 #include "base/base_switches.h" | 10 #include "base/base_switches.h" |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 126 static void Delete(base::ConditionVariable* instance) { | 126 static void Delete(base::ConditionVariable* instance) { |
| 127 instance->~ConditionVariable(); | 127 instance->~ConditionVariable(); |
| 128 } | 128 } |
| 129 }; | 129 }; |
| 130 | 130 |
| 131 // A condition variable that synchronize threads initializing and waiting | 131 // A condition variable that synchronize threads initializing and waiting |
| 132 // for g_child_thread. | 132 // for g_child_thread. |
| 133 base::LazyInstance<base::ConditionVariable, CondVarLazyInstanceTraits> | 133 base::LazyInstance<base::ConditionVariable, CondVarLazyInstanceTraits> |
| 134 g_lazy_child_thread_cv = LAZY_INSTANCE_INITIALIZER; | 134 g_lazy_child_thread_cv = LAZY_INSTANCE_INITIALIZER; |
| 135 | 135 |
| 136 void QuitMainThreadMessageLoop() { | |
| 137 base::MessageLoop::current()->Quit(); | |
| 138 } | |
| 139 | |
| 140 #endif | 136 #endif |
| 141 | 137 |
| 142 } // namespace | 138 } // namespace |
| 143 | 139 |
| 144 ChildThread::ChildThread() | 140 ChildThread::ChildThread() |
| 145 : channel_connected_factory_(this), | 141 : channel_connected_factory_(this), |
| 146 in_browser_process_(false) { | 142 in_browser_process_(false) { |
| 147 channel_name_ = CommandLine::ForCurrentProcess()->GetSwitchValueASCII( | 143 channel_name_ = CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |
| 148 switches::kProcessChannelID); | 144 switches::kProcessChannelID); |
| 149 Init(); | 145 Init(); |
| (...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 442 base::allocator::GetStats(buffer, sizeof(buffer)); | 438 base::allocator::GetStats(buffer, sizeof(buffer)); |
| 443 result.append(buffer); | 439 result.append(buffer); |
| 444 Send(new ChildProcessHostMsg_TcmallocStats(result)); | 440 Send(new ChildProcessHostMsg_TcmallocStats(result)); |
| 445 } | 441 } |
| 446 #endif | 442 #endif |
| 447 | 443 |
| 448 ChildThread* ChildThread::current() { | 444 ChildThread* ChildThread::current() { |
| 449 return g_lazy_tls.Pointer()->Get(); | 445 return g_lazy_tls.Pointer()->Get(); |
| 450 } | 446 } |
| 451 | 447 |
| 452 #if defined(OS_ANDROID) | |
| 453 // The method must NOT be called on the child thread itself. | |
| 454 // It may block the child thread if so. | |
| 455 void ChildThread::ShutdownThread() { | |
| 456 DCHECK(!ChildThread::current()) << | |
| 457 "this method should NOT be called from child thread itself"; | |
| 458 { | |
| 459 base::AutoLock lock(g_lazy_child_thread_lock.Get()); | |
| 460 while (!g_child_thread) | |
| 461 g_lazy_child_thread_cv.Get().Wait(); | |
| 462 } | |
| 463 DCHECK_NE(base::MessageLoop::current(), g_child_thread->message_loop()); | |
| 464 g_child_thread->message_loop()->PostTask( | |
| 465 FROM_HERE, base::Bind(&QuitMainThreadMessageLoop)); | |
| 466 } | |
| 467 | |
| 468 #endif | |
| 469 | |
| 470 void ChildThread::OnProcessFinalRelease() { | 448 void ChildThread::OnProcessFinalRelease() { |
| 471 if (on_channel_error_called_) { | 449 if (on_channel_error_called_) { |
| 472 base::MessageLoop::current()->Quit(); | 450 base::MessageLoop::current()->Quit(); |
| 473 return; | 451 return; |
| 474 } | 452 } |
| 475 | 453 |
| 476 // The child process shutdown sequence is a request response based mechanism, | 454 // The child process shutdown sequence is a request response based mechanism, |
| 477 // where we send out an initial feeler request to the child process host | 455 // where we send out an initial feeler request to the child process host |
| 478 // instance in the browser to verify if it's ok to shutdown the child process. | 456 // instance in the browser to verify if it's ok to shutdown the child process. |
| 479 // The browser then sends back a response if it's ok to shutdown. This avoids | 457 // The browser then sends back a response if it's ok to shutdown. This avoids |
| 480 // race conditions if the process refcount is 0 but there's an IPC message | 458 // race conditions if the process refcount is 0 but there's an IPC message |
| 481 // inflight that would addref it. | 459 // inflight that would addref it. |
| 482 Send(new ChildProcessHostMsg_ShutdownRequest); | 460 Send(new ChildProcessHostMsg_ShutdownRequest); |
| 483 } | 461 } |
| 484 | 462 |
| 485 void ChildThread::EnsureConnected() { | 463 void ChildThread::EnsureConnected() { |
| 486 VLOG(0) << "ChildThread::EnsureConnected()"; | 464 VLOG(0) << "ChildThread::EnsureConnected()"; |
| 487 base::KillProcess(base::GetCurrentProcessHandle(), 0, false); | 465 base::KillProcess(base::GetCurrentProcessHandle(), 0, false); |
| 488 } | 466 } |
| 489 | 467 |
| 490 } // namespace content | 468 } // namespace content |
| OLD | NEW |