| 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.h> | 7 #include <string.h> |
| 8 | 8 |
| 9 #include <string> | 9 #include <string> |
| 10 | 10 |
| 11 #include "base/atomicops.h" | 11 #include "base/atomicops.h" |
| 12 #include "base/bind.h" | 12 #include "base/bind.h" |
| 13 #include "base/compiler_specific.h" | 13 #include "base/compiler_specific.h" |
| 14 #include "base/lazy_instance.h" | 14 #include "base/lazy_instance.h" |
| 15 #include "base/macros.h" | 15 #include "base/macros.h" |
| 16 #include "base/profiler/scoped_tracker.h" | 16 #include "base/profiler/scoped_tracker.h" |
| 17 #include "base/single_thread_task_runner.h" | 17 #include "base/single_thread_task_runner.h" |
| 18 #include "base/threading/platform_thread.h" |
| 18 #include "base/threading/sequenced_worker_pool.h" | 19 #include "base/threading/sequenced_worker_pool.h" |
| 19 #include "build/build_config.h" | 20 #include "build/build_config.h" |
| 20 #include "content/public/browser/browser_thread_delegate.h" | 21 #include "content/public/browser/browser_thread_delegate.h" |
| 21 #include "content/public/browser/content_browser_client.h" | 22 #include "content/public/browser/content_browser_client.h" |
| 22 #include "net/disk_cache/simple/simple_backend_impl.h" | 23 #include "net/disk_cache/simple/simple_backend_impl.h" |
| 23 | 24 |
| 24 #if defined(OS_ANDROID) | 25 #if defined(OS_ANDROID) |
| 25 #include "base/android/jni_android.h" | 26 #include "base/android/jni_android.h" |
| 26 #endif | 27 #endif |
| 27 | 28 |
| 28 namespace content { | 29 namespace content { |
| 29 | 30 |
| 30 namespace { | 31 namespace { |
| 31 | 32 |
| 32 // Friendly names for the well-known threads. | 33 // Friendly names for the well-known threads. |
| 33 static const char* const g_browser_thread_names[BrowserThread::ID_COUNT] = { | 34 static const char* const g_browser_thread_names[BrowserThread::ID_COUNT] = { |
| 34 "", // UI (name assembled in browser_main.cc). | 35 "", // UI (name assembled in browser_main.cc). |
| 35 "Chrome_DBThread", // DB | 36 "Chrome_DBThread", // DB |
| 36 "Chrome_FileThread", // FILE | 37 "Chrome_FileThread", // FILE |
| 37 "Chrome_FileUserBlockingThread", // FILE_USER_BLOCKING | 38 "Chrome_FileUserBlockingThread", // FILE_USER_BLOCKING |
| 38 "Chrome_ProcessLauncherThread", // PROCESS_LAUNCHER | 39 "Chrome_ProcessLauncherThread", // PROCESS_LAUNCHER |
| 39 "Chrome_CacheThread", // CACHE | 40 "Chrome_CacheThread", // CACHE |
| 40 "Chrome_IOThread", // IO | 41 "Chrome_IOThread", // IO |
| 41 }; | 42 }; |
| 42 | 43 |
| 44 static const char* GetThreadName(BrowserThread::ID thread) { |
| 45 if (BrowserThread::UI < thread && thread < BrowserThread::ID_COUNT) |
| 46 return g_browser_thread_names[thread]; |
| 47 if (thread == BrowserThread::UI) |
| 48 return "Chrome_UIThread"; |
| 49 return "Unknown Thread"; |
| 50 } |
| 51 |
| 43 // An implementation of SingleThreadTaskRunner to be used in conjunction | 52 // An implementation of SingleThreadTaskRunner to be used in conjunction |
| 44 // with BrowserThread. | 53 // with BrowserThread. |
| 45 class BrowserThreadTaskRunner : public base::SingleThreadTaskRunner { | 54 class BrowserThreadTaskRunner : public base::SingleThreadTaskRunner { |
| 46 public: | 55 public: |
| 47 explicit BrowserThreadTaskRunner(BrowserThread::ID identifier) | 56 explicit BrowserThreadTaskRunner(BrowserThread::ID identifier) |
| 48 : id_(identifier) {} | 57 : id_(identifier) {} |
| 49 | 58 |
| 50 // SingleThreadTaskRunner implementation. | 59 // SingleThreadTaskRunner implementation. |
| 51 bool PostDelayedTask(const tracked_objects::Location& from_here, | 60 bool PostDelayedTask(const tracked_objects::Location& from_here, |
| 52 const base::Closure& task, | 61 const base::Closure& task, |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 113 | 122 |
| 114 const scoped_refptr<base::SequencedWorkerPool> blocking_pool; | 123 const scoped_refptr<base::SequencedWorkerPool> blocking_pool; |
| 115 }; | 124 }; |
| 116 | 125 |
| 117 base::LazyInstance<BrowserThreadGlobals>::Leaky | 126 base::LazyInstance<BrowserThreadGlobals>::Leaky |
| 118 g_globals = LAZY_INSTANCE_INITIALIZER; | 127 g_globals = LAZY_INSTANCE_INITIALIZER; |
| 119 | 128 |
| 120 } // namespace | 129 } // namespace |
| 121 | 130 |
| 122 BrowserThreadImpl::BrowserThreadImpl(ID identifier) | 131 BrowserThreadImpl::BrowserThreadImpl(ID identifier) |
| 123 : Thread(g_browser_thread_names[identifier]), | 132 : Thread(GetThreadName(identifier)), identifier_(identifier) { |
| 124 identifier_(identifier) { | |
| 125 Initialize(); | 133 Initialize(); |
| 126 } | 134 } |
| 127 | 135 |
| 128 BrowserThreadImpl::BrowserThreadImpl(ID identifier, | 136 BrowserThreadImpl::BrowserThreadImpl(ID identifier, |
| 129 base::MessageLoop* message_loop) | 137 base::MessageLoop* message_loop) |
| 130 : Thread(message_loop->thread_name()), identifier_(identifier) { | 138 : Thread(GetThreadName(identifier)), identifier_(identifier) { |
| 131 set_message_loop(message_loop); | 139 set_message_loop(message_loop); |
| 132 Initialize(); | 140 Initialize(); |
| 133 } | 141 } |
| 134 | 142 |
| 135 // static | 143 // static |
| 136 void BrowserThreadImpl::ShutdownThreadPool() { | 144 void BrowserThreadImpl::ShutdownThreadPool() { |
| 137 // The goal is to make it impossible for chrome to 'infinite loop' during | 145 // The goal is to make it impossible for chrome to 'infinite loop' during |
| 138 // shutdown, but to reasonably expect that all BLOCKING_SHUTDOWN tasks queued | 146 // shutdown, but to reasonably expect that all BLOCKING_SHUTDOWN tasks queued |
| 139 // during shutdown get run. There's nothing particularly scientific about the | 147 // during shutdown get run. There's nothing particularly scientific about the |
| 140 // number chosen. | 148 // number chosen. |
| (...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 410 // static | 418 // static |
| 411 bool BrowserThread::CurrentlyOn(ID identifier) { | 419 bool BrowserThread::CurrentlyOn(ID identifier) { |
| 412 BrowserThreadGlobals& globals = g_globals.Get(); | 420 BrowserThreadGlobals& globals = g_globals.Get(); |
| 413 base::AutoLock lock(globals.lock); | 421 base::AutoLock lock(globals.lock); |
| 414 DCHECK(identifier >= 0 && identifier < ID_COUNT); | 422 DCHECK(identifier >= 0 && identifier < ID_COUNT); |
| 415 return globals.threads[identifier] && | 423 return globals.threads[identifier] && |
| 416 globals.threads[identifier]->message_loop() == | 424 globals.threads[identifier]->message_loop() == |
| 417 base::MessageLoop::current(); | 425 base::MessageLoop::current(); |
| 418 } | 426 } |
| 419 | 427 |
| 420 static const char* GetThreadName(BrowserThread::ID thread) { | |
| 421 if (BrowserThread::UI < thread && thread < BrowserThread::ID_COUNT) | |
| 422 return g_browser_thread_names[thread]; | |
| 423 if (thread == BrowserThread::UI) | |
| 424 return "Chrome_UIThread"; | |
| 425 return "Unknown Thread"; | |
| 426 } | |
| 427 | |
| 428 // static | 428 // static |
| 429 std::string BrowserThread::GetDCheckCurrentlyOnErrorMessage(ID expected) { | 429 std::string BrowserThread::GetDCheckCurrentlyOnErrorMessage(ID expected) { |
| 430 const base::MessageLoop* message_loop = base::MessageLoop::current(); | 430 std::string actual_name = base::PlatformThread::GetName(); |
| 431 ID actual_browser_thread; | 431 if (actual_name.empty()) |
| 432 const char* actual_name = "Unknown Thread"; | 432 actual_name = "Unknown Thread"; |
| 433 if (message_loop && !message_loop->thread_name().empty()) { | 433 |
| 434 actual_name = message_loop->thread_name().c_str(); | |
| 435 } else if (GetCurrentThreadIdentifier(&actual_browser_thread)) { | |
| 436 actual_name = GetThreadName(actual_browser_thread); | |
| 437 } | |
| 438 std::string result = "Must be called on "; | 434 std::string result = "Must be called on "; |
| 439 result += GetThreadName(expected); | 435 result += GetThreadName(expected); |
| 440 result += "; actually called on "; | 436 result += "; actually called on "; |
| 441 result += actual_name; | 437 result += actual_name; |
| 442 result += "."; | 438 result += "."; |
| 443 return result; | 439 return result; |
| 444 } | 440 } |
| 445 | 441 |
| 446 // static | 442 // static |
| 447 bool BrowserThread::IsMessageLoopValid(ID identifier) { | 443 bool BrowserThread::IsMessageLoopValid(ID identifier) { |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 552 AtomicWord* storage = reinterpret_cast<AtomicWord*>( | 548 AtomicWord* storage = reinterpret_cast<AtomicWord*>( |
| 553 &globals.thread_delegates[identifier]); | 549 &globals.thread_delegates[identifier]); |
| 554 AtomicWord old_pointer = base::subtle::NoBarrier_AtomicExchange( | 550 AtomicWord old_pointer = base::subtle::NoBarrier_AtomicExchange( |
| 555 storage, reinterpret_cast<AtomicWord>(delegate)); | 551 storage, reinterpret_cast<AtomicWord>(delegate)); |
| 556 | 552 |
| 557 // This catches registration when previously registered. | 553 // This catches registration when previously registered. |
| 558 DCHECK(!delegate || !old_pointer); | 554 DCHECK(!delegate || !old_pointer); |
| 559 } | 555 } |
| 560 | 556 |
| 561 } // namespace content | 557 } // namespace content |
| OLD | NEW |