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 |