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_impl.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 |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
154 } | 154 } |
155 | 155 |
156 protected: | 156 protected: |
157 ~SuicideOnChannelErrorFilter() override {} | 157 ~SuicideOnChannelErrorFilter() override {} |
158 }; | 158 }; |
159 | 159 |
160 #endif // OS(POSIX) | 160 #endif // OS(POSIX) |
161 | 161 |
162 #if defined(OS_ANDROID) | 162 #if defined(OS_ANDROID) |
163 ChildThreadImpl* g_child_thread = NULL; | 163 ChildThreadImpl* g_child_thread = NULL; |
164 bool g_child_thread_initialized = false; | |
164 | 165 |
165 // A lock protects g_child_thread. | 166 // A lock protects g_child_thread. |
166 base::LazyInstance<base::Lock> g_lazy_child_thread_lock = | 167 base::LazyInstance<base::Lock> g_lazy_child_thread_lock = |
no sievers
2015/02/18 20:48:30
base::LazyInstance<base::Lock>::Leaky
aelias_OOO_until_Jul13
2015/02/19 01:00:28
Done.
| |
167 LAZY_INSTANCE_INITIALIZER; | 168 LAZY_INSTANCE_INITIALIZER; |
168 | 169 |
169 // base::ConditionVariable has an explicit constructor that takes | 170 // base::ConditionVariable has an explicit constructor that takes |
170 // a base::Lock pointer as parameter. The base::DefaultLazyInstanceTraits | 171 // a base::Lock pointer as parameter. The base::DefaultLazyInstanceTraits |
171 // doesn't handle the case. Thus, we need our own class here. | 172 // doesn't handle the case. Thus, we need our own class here. |
172 struct CondVarLazyInstanceTraits { | 173 struct CondVarLazyInstanceTraits { |
173 static const bool kRegisterOnExit = true; | 174 static const bool kRegisterOnExit = true; |
no sievers
2015/02/18 20:48:30
kRegisterOnExit = false;
should have the same eff
aelias_OOO_until_Jul13
2015/02/19 01:00:28
OK, set to "false". I stayed with the traits to k
| |
174 #ifndef NDEBUG | 175 #ifndef NDEBUG |
175 static const bool kAllowedToAccessOnNonjoinableThread = false; | 176 static const bool kAllowedToAccessOnNonjoinableThread = false; |
no sievers
2015/02/18 20:48:30
Hmm, this might be wrong too since the thread we c
aelias_OOO_until_Jul13
2015/02/19 01:00:28
Changed to "true".
| |
176 #endif | 177 #endif |
177 | 178 |
178 static base::ConditionVariable* New(void* instance) { | 179 static base::ConditionVariable* New(void* instance) { |
179 return new (instance) base::ConditionVariable( | 180 return new (instance) base::ConditionVariable( |
180 g_lazy_child_thread_lock.Pointer()); | 181 g_lazy_child_thread_lock.Pointer()); |
181 } | 182 } |
182 static void Delete(base::ConditionVariable* instance) { | 183 static void Delete(base::ConditionVariable* instance) { |
183 instance->~ConditionVariable(); | 184 instance->~ConditionVariable(); |
184 } | 185 } |
185 }; | 186 }; |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
366 base::MessageLoop::current()->PostDelayedTask( | 367 base::MessageLoop::current()->PostDelayedTask( |
367 FROM_HERE, | 368 FROM_HERE, |
368 base::Bind(&ChildThreadImpl::EnsureConnected, | 369 base::Bind(&ChildThreadImpl::EnsureConnected, |
369 channel_connected_factory_.GetWeakPtr()), | 370 channel_connected_factory_.GetWeakPtr()), |
370 base::TimeDelta::FromSeconds(connection_timeout)); | 371 base::TimeDelta::FromSeconds(connection_timeout)); |
371 | 372 |
372 #if defined(OS_ANDROID) | 373 #if defined(OS_ANDROID) |
373 { | 374 { |
374 base::AutoLock lock(g_lazy_child_thread_lock.Get()); | 375 base::AutoLock lock(g_lazy_child_thread_lock.Get()); |
375 g_child_thread = this; | 376 g_child_thread = this; |
377 g_child_thread_initialized = true; | |
376 } | 378 } |
377 // Signalling without locking is fine here because only | 379 // Signalling without locking is fine here because only |
378 // one thread can wait on the condition variable. | 380 // one thread can wait on the condition variable. |
379 g_lazy_child_thread_cv.Get().Signal(); | 381 g_lazy_child_thread_cv.Get().Signal(); |
380 #endif | 382 #endif |
381 | 383 |
382 #if defined(TCMALLOC_TRACE_MEMORY_SUPPORTED) | 384 #if defined(TCMALLOC_TRACE_MEMORY_SUPPORTED) |
383 trace_memory_controller_.reset(new base::trace_event::TraceMemoryController( | 385 trace_memory_controller_.reset(new base::trace_event::TraceMemoryController( |
384 message_loop_->message_loop_proxy(), ::HeapProfilerWithPseudoStackStart, | 386 message_loop_->message_loop_proxy(), ::HeapProfilerWithPseudoStackStart, |
385 ::HeapProfilerStop, ::GetHeapProfile)); | 387 ::HeapProfilerStop, ::GetHeapProfile)); |
386 #endif | 388 #endif |
387 | 389 |
388 shared_bitmap_manager_.reset( | 390 shared_bitmap_manager_.reset( |
389 new ChildSharedBitmapManager(thread_safe_sender())); | 391 new ChildSharedBitmapManager(thread_safe_sender())); |
390 | 392 |
391 gpu_memory_buffer_manager_.reset( | 393 gpu_memory_buffer_manager_.reset( |
392 new ChildGpuMemoryBufferManager(thread_safe_sender())); | 394 new ChildGpuMemoryBufferManager(thread_safe_sender())); |
393 | 395 |
394 discardable_shared_memory_manager_.reset( | 396 discardable_shared_memory_manager_.reset( |
395 new ChildDiscardableSharedMemoryManager(thread_safe_sender())); | 397 new ChildDiscardableSharedMemoryManager(thread_safe_sender())); |
396 } | 398 } |
397 | 399 |
398 ChildThreadImpl::~ChildThreadImpl() { | 400 ChildThreadImpl::~ChildThreadImpl() { |
401 #if defined(OS_ANDROID) | |
402 { | |
403 base::AutoLock lock(g_lazy_child_thread_lock.Get()); | |
404 g_child_thread = nullptr; | |
405 } | |
406 #endif | |
407 | |
399 #ifdef IPC_MESSAGE_LOG_ENABLED | 408 #ifdef IPC_MESSAGE_LOG_ENABLED |
400 IPC::Logging::GetInstance()->SetIPCSender(NULL); | 409 IPC::Logging::GetInstance()->SetIPCSender(NULL); |
401 #endif | 410 #endif |
402 | 411 |
403 channel_->RemoveFilter(histogram_message_filter_.get()); | 412 channel_->RemoveFilter(histogram_message_filter_.get()); |
404 channel_->RemoveFilter(sync_message_filter_.get()); | 413 channel_->RemoveFilter(sync_message_filter_.get()); |
405 | 414 |
406 // The ChannelProxy object caches a pointer to the IPC thread, so need to | 415 // 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. | 416 // 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 | 417 // NOTE: this also has the side-effect of not closing the main IPC channel to |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
591 return g_lazy_tls.Pointer()->Get(); | 600 return g_lazy_tls.Pointer()->Get(); |
592 } | 601 } |
593 | 602 |
594 #if defined(OS_ANDROID) | 603 #if defined(OS_ANDROID) |
595 // The method must NOT be called on the child thread itself. | 604 // The method must NOT be called on the child thread itself. |
596 // It may block the child thread if so. | 605 // It may block the child thread if so. |
597 void ChildThreadImpl::ShutdownThread() { | 606 void ChildThreadImpl::ShutdownThread() { |
598 DCHECK(!ChildThreadImpl::current()) << | 607 DCHECK(!ChildThreadImpl::current()) << |
599 "this method should NOT be called from child thread itself"; | 608 "this method should NOT be called from child thread itself"; |
600 { | 609 { |
601 base::AutoLock lock(g_lazy_child_thread_lock.Get()); | 610 base::AutoLock lock(g_lazy_child_thread_lock.Get()); |
no sievers
2015/02/18 19:19:42
What about the two lazy instances (lock and cv), c
aelias_OOO_until_Jul13
2015/02/18 19:37:27
One hint FWIW is that this is a preexisting proble
no sievers
2015/02/18 20:48:30
I think it's wrong that we access the lazy instanc
aelias_OOO_until_Jul13
2015/02/19 01:00:28
Done.
| |
602 while (!g_child_thread) | 611 while (!g_child_thread_initialized) |
603 g_lazy_child_thread_cv.Get().Wait(); | 612 g_lazy_child_thread_cv.Get().Wait(); |
613 | |
614 // g_child_thread may already have been destructed elsewhere. | |
no sievers
2015/02/18 19:19:42
nit: "...may already have been destructed while we
| |
615 if (!g_child_thread) | |
616 return; | |
Feng Qian
2015/02/18 01:47:32
Seems that only path to get here is that ChildThre
aelias_OOO_until_Jul13
2015/02/18 02:46:52
As discussed offline, ~ChildThreadImpl is called f
| |
617 | |
618 DCHECK_NE(base::MessageLoop::current(), g_child_thread->message_loop()); | |
619 g_child_thread->message_loop()->PostTask( | |
620 FROM_HERE, base::Bind(&QuitMainThreadMessageLoop)); | |
604 } | 621 } |
605 DCHECK_NE(base::MessageLoop::current(), g_child_thread->message_loop()); | |
606 g_child_thread->message_loop()->PostTask( | |
607 FROM_HERE, base::Bind(&QuitMainThreadMessageLoop)); | |
608 } | 622 } |
609 #endif | 623 #endif |
610 | 624 |
611 void ChildThreadImpl::OnProcessFinalRelease() { | 625 void ChildThreadImpl::OnProcessFinalRelease() { |
612 if (on_channel_error_called_) { | 626 if (on_channel_error_called_) { |
613 base::MessageLoop::current()->Quit(); | 627 base::MessageLoop::current()->Quit(); |
614 return; | 628 return; |
615 } | 629 } |
616 | 630 |
617 // The child process shutdown sequence is a request response based mechanism, | 631 // The child process shutdown sequence is a request response based mechanism, |
(...skipping 12 matching lines...) Expand all Loading... | |
630 | 644 |
631 void ChildThreadImpl::OnProcessBackgrounded(bool background) { | 645 void ChildThreadImpl::OnProcessBackgrounded(bool background) { |
632 // Set timer slack to maximum on main thread when in background. | 646 // Set timer slack to maximum on main thread when in background. |
633 base::TimerSlack timer_slack = base::TIMER_SLACK_NONE; | 647 base::TimerSlack timer_slack = base::TIMER_SLACK_NONE; |
634 if (background) | 648 if (background) |
635 timer_slack = base::TIMER_SLACK_MAXIMUM; | 649 timer_slack = base::TIMER_SLACK_MAXIMUM; |
636 base::MessageLoop::current()->SetTimerSlack(timer_slack); | 650 base::MessageLoop::current()->SetTimerSlack(timer_slack); |
637 } | 651 } |
638 | 652 |
639 } // namespace content | 653 } // namespace content |
OLD | NEW |