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/browser/browser_thread_impl.h" | 5 #include "content/browser/browser_thread_impl.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/atomicops.h" | 10 #include "base/atomicops.h" |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
126 "BrowserBlocking", | 126 "BrowserBlocking", |
127 base::TaskPriority::USER_VISIBLE)) {} | 127 base::TaskPriority::USER_VISIBLE)) {} |
128 | 128 |
129 // This lock protects |task_runners| and |states|. Do not read or modify those | 129 // This lock protects |task_runners| and |states|. Do not read or modify those |
130 // arrays without holding this lock. Do not block while holding this lock. | 130 // arrays without holding this lock. Do not block while holding this lock. |
131 base::Lock lock; | 131 base::Lock lock; |
132 | 132 |
133 // This array is filled either as the underlying threads start and invoke | 133 // This array is filled either as the underlying threads start and invoke |
134 // Init() or in RedirectThreadIDToTaskRunner() for threads that are being | 134 // Init() or in RedirectThreadIDToTaskRunner() for threads that are being |
135 // redirected. It is not emptied during shutdown in order to support | 135 // redirected. It is not emptied during shutdown in order to support |
136 // RunsTasksOnCurrentThread() until the very end. | 136 // RunsTasksInCurrentSequence() until the very end. |
137 scoped_refptr<base::SingleThreadTaskRunner> | 137 scoped_refptr<base::SingleThreadTaskRunner> |
138 task_runners[BrowserThread::ID_COUNT]; | 138 task_runners[BrowserThread::ID_COUNT]; |
139 | 139 |
140 // Holds the state of each BrowserThread::ID. | 140 // Holds the state of each BrowserThread::ID. |
141 BrowserThreadState states[BrowserThread::ID_COUNT] = {}; | 141 BrowserThreadState states[BrowserThread::ID_COUNT] = {}; |
142 | 142 |
143 // Only atomic operations are used on this pointer. The delegate isn't owned | 143 // Only atomic operations are used on this pointer. The delegate isn't owned |
144 // by BrowserThreadGlobals, rather by whoever calls | 144 // by BrowserThreadGlobals, rather by whoever calls |
145 // BrowserThread::SetIOThreadDelegate. | 145 // BrowserThread::SetIOThreadDelegate. |
146 BrowserThreadDelegateAtomicPtr io_thread_delegate = 0; | 146 BrowserThreadDelegateAtomicPtr io_thread_delegate = 0; |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
201 | 201 |
202 #if DCHECK_IS_ON() | 202 #if DCHECK_IS_ON() |
203 { | 203 { |
204 base::AutoLock lock(globals.lock); | 204 base::AutoLock lock(globals.lock); |
205 // |globals| should already have been initialized for |identifier_| in | 205 // |globals| should already have been initialized for |identifier_| in |
206 // BrowserThreadImpl::StartWithOptions(). If this isn't the case it's likely | 206 // BrowserThreadImpl::StartWithOptions(). If this isn't the case it's likely |
207 // because this BrowserThreadImpl's owner incorrectly used Thread::Start.*() | 207 // because this BrowserThreadImpl's owner incorrectly used Thread::Start.*() |
208 // instead of BrowserThreadImpl::Start.*(). | 208 // instead of BrowserThreadImpl::Start.*(). |
209 DCHECK_EQ(globals.states[identifier_], BrowserThreadState::RUNNING); | 209 DCHECK_EQ(globals.states[identifier_], BrowserThreadState::RUNNING); |
210 DCHECK(globals.task_runners[identifier_]); | 210 DCHECK(globals.task_runners[identifier_]); |
211 DCHECK(globals.task_runners[identifier_]->RunsTasksOnCurrentThread()); | 211 DCHECK(globals.task_runners[identifier_]->RunsTasksInCurrentSequence()); |
212 } | 212 } |
213 #endif // DCHECK_IS_ON() | 213 #endif // DCHECK_IS_ON() |
214 | 214 |
215 if (identifier_ == BrowserThread::DB || | 215 if (identifier_ == BrowserThread::DB || |
216 identifier_ == BrowserThread::FILE || | 216 identifier_ == BrowserThread::FILE || |
217 identifier_ == BrowserThread::FILE_USER_BLOCKING || | 217 identifier_ == BrowserThread::FILE_USER_BLOCKING || |
218 identifier_ == BrowserThread::PROCESS_LAUNCHER || | 218 identifier_ == BrowserThread::PROCESS_LAUNCHER || |
219 identifier_ == BrowserThread::CACHE) { | 219 identifier_ == BrowserThread::CACHE) { |
220 // Nesting and task observers are not allowed on redirected threads. | 220 // Nesting and task observers are not allowed on redirected threads. |
221 base::RunLoop::DisallowNestingOnCurrentThread(); | 221 base::RunLoop::DisallowNestingOnCurrentThread(); |
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
567 globals.states[identifier] == BrowserThreadState::RUNNING; | 567 globals.states[identifier] == BrowserThreadState::RUNNING; |
568 } | 568 } |
569 | 569 |
570 // static | 570 // static |
571 bool BrowserThread::CurrentlyOn(ID identifier) { | 571 bool BrowserThread::CurrentlyOn(ID identifier) { |
572 BrowserThreadGlobals& globals = g_globals.Get(); | 572 BrowserThreadGlobals& globals = g_globals.Get(); |
573 base::AutoLock lock(globals.lock); | 573 base::AutoLock lock(globals.lock); |
574 DCHECK_GE(identifier, 0); | 574 DCHECK_GE(identifier, 0); |
575 DCHECK_LT(identifier, ID_COUNT); | 575 DCHECK_LT(identifier, ID_COUNT); |
576 return globals.task_runners[identifier] && | 576 return globals.task_runners[identifier] && |
577 globals.task_runners[identifier]->RunsTasksOnCurrentThread(); | 577 globals.task_runners[identifier]->RunsTasksInCurrentSequence(); |
578 } | 578 } |
579 | 579 |
580 // static | 580 // static |
581 std::string BrowserThread::GetDCheckCurrentlyOnErrorMessage(ID expected) { | 581 std::string BrowserThread::GetDCheckCurrentlyOnErrorMessage(ID expected) { |
582 std::string actual_name = base::PlatformThread::GetName(); | 582 std::string actual_name = base::PlatformThread::GetName(); |
583 if (actual_name.empty()) | 583 if (actual_name.empty()) |
584 actual_name = "Unknown Thread"; | 584 actual_name = "Unknown Thread"; |
585 | 585 |
586 std::string result = "Must be called on "; | 586 std::string result = "Must be called on "; |
587 result += GetThreadName(expected); | 587 result += GetThreadName(expected); |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
654 return false; | 654 return false; |
655 | 655 |
656 BrowserThreadGlobals& globals = g_globals.Get(); | 656 BrowserThreadGlobals& globals = g_globals.Get(); |
657 // Profiler to track potential contention on |globals.lock|. This only does | 657 // Profiler to track potential contention on |globals.lock|. This only does |
658 // real work on canary and local dev builds, so the cost of having this here | 658 // real work on canary and local dev builds, so the cost of having this here |
659 // should be minimal. | 659 // should be minimal. |
660 tracked_objects::ScopedTracker tracking_profile(FROM_HERE); | 660 tracked_objects::ScopedTracker tracking_profile(FROM_HERE); |
661 base::AutoLock lock(globals.lock); | 661 base::AutoLock lock(globals.lock); |
662 for (int i = 0; i < ID_COUNT; ++i) { | 662 for (int i = 0; i < ID_COUNT; ++i) { |
663 if (globals.task_runners[i] && | 663 if (globals.task_runners[i] && |
664 globals.task_runners[i]->RunsTasksOnCurrentThread()) { | 664 globals.task_runners[i]->RunsTasksInCurrentSequence()) { |
665 *identifier = static_cast<ID>(i); | 665 *identifier = static_cast<ID>(i); |
666 return true; | 666 return true; |
667 } | 667 } |
668 } | 668 } |
669 | 669 |
670 return false; | 670 return false; |
671 } | 671 } |
672 | 672 |
673 // static | 673 // static |
674 scoped_refptr<base::SingleThreadTaskRunner> | 674 scoped_refptr<base::SingleThreadTaskRunner> |
675 BrowserThread::GetTaskRunnerForThread(ID identifier) { | 675 BrowserThread::GetTaskRunnerForThread(ID identifier) { |
676 return g_task_runners.Get().proxies[identifier]; | 676 return g_task_runners.Get().proxies[identifier]; |
677 } | 677 } |
678 | 678 |
679 // static | 679 // static |
680 void BrowserThread::SetIOThreadDelegate(BrowserThreadDelegate* delegate) { | 680 void BrowserThread::SetIOThreadDelegate(BrowserThreadDelegate* delegate) { |
681 BrowserThreadGlobals& globals = g_globals.Get(); | 681 BrowserThreadGlobals& globals = g_globals.Get(); |
682 BrowserThreadDelegateAtomicPtr old_delegate = | 682 BrowserThreadDelegateAtomicPtr old_delegate = |
683 base::subtle::NoBarrier_AtomicExchange( | 683 base::subtle::NoBarrier_AtomicExchange( |
684 &globals.io_thread_delegate, | 684 &globals.io_thread_delegate, |
685 reinterpret_cast<BrowserThreadDelegateAtomicPtr>(delegate)); | 685 reinterpret_cast<BrowserThreadDelegateAtomicPtr>(delegate)); |
686 | 686 |
687 // This catches registration when previously registered. | 687 // This catches registration when previously registered. |
688 DCHECK(!delegate || !old_delegate); | 688 DCHECK(!delegate || !old_delegate); |
689 } | 689 } |
690 | 690 |
691 } // namespace content | 691 } // namespace content |
OLD | NEW |