| 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 |