| Index: content/browser/browser_thread_impl.cc
|
| ===================================================================
|
| --- content/browser/browser_thread_impl.cc (revision 111697)
|
| +++ content/browser/browser_thread_impl.cc (working copy)
|
| @@ -4,19 +4,16 @@
|
|
|
| #include "content/browser/browser_thread_impl.h"
|
|
|
| -#include "base/atomicops.h"
|
| #include "base/bind.h"
|
| #include "base/lazy_instance.h"
|
| #include "base/message_loop.h"
|
| #include "base/message_loop_proxy.h"
|
| #include "base/threading/thread_restrictions.h"
|
|
|
| -namespace content {
|
| -
|
| namespace {
|
|
|
| // Friendly names for the well-known threads.
|
| -static const char* g_browser_thread_names[BrowserThread::ID_COUNT] = {
|
| +static const char* browser_thread_names[content::BrowserThread::ID_COUNT] = {
|
| "", // UI (name assembled in browser_main.cc).
|
| "Chrome_DBThread", // DB
|
| "Chrome_WebKitThread", // WEBKIT
|
| @@ -29,86 +26,38 @@
|
| #endif
|
| };
|
|
|
| -// This lock protects |g_browser_threads|. Do not read or modify that
|
| -// array without holding this lock. Do not block while holding this
|
| -// lock.
|
| +} // namespace
|
| +
|
| +namespace content {
|
| +
|
| +namespace {
|
| +
|
| +// This lock protects |g_browser_threads|. Do not read or modify that array
|
| +// without holding this lock. Do not block while holding this lock.
|
| base::LazyInstance<base::Lock,
|
| base::LeakyLazyInstanceTraits<base::Lock> >
|
| g_lock = LAZY_INSTANCE_INITIALIZER;
|
|
|
| -// This array is protected by |g_lock|. The threads are not owned by this
|
| -// array. Typically, the threads are owned on the UI thread by
|
| -// content::BrowserMainLoop. BrowserThreadImpl objects remove
|
| +
|
| +// An array of the BrowserThread objects. This array is protected by |g_lock|.
|
| +// The threads are not owned by this array. Typically, the threads are owned
|
| +// on the UI thread by the g_browser_process object. BrowserThreads remove
|
| // themselves from this array upon destruction.
|
| -static BrowserThreadImpl* g_browser_threads[BrowserThread::ID_COUNT];
|
| +BrowserThread* g_browser_threads[BrowserThread::ID_COUNT];
|
|
|
| -// Only atomic operations are used on this array. The delegates are
|
| -// not owned by this array, rather by whoever calls
|
| -// BrowserThread::SetDelegate.
|
| -static BrowserThreadDelegate* g_browser_thread_delegates[
|
| - BrowserThread::ID_COUNT];
|
| -
|
| } // namespace
|
|
|
| -BrowserThreadImpl::BrowserThreadImpl(ID identifier)
|
| - : Thread(g_browser_thread_names[identifier]),
|
| - identifier_(identifier) {
|
| - Initialize();
|
| +BrowserThreadImpl::BrowserThreadImpl(BrowserThread::ID identifier)
|
| + : BrowserThread(identifier) {
|
| }
|
|
|
| -BrowserThreadImpl::BrowserThreadImpl(ID identifier,
|
| +BrowserThreadImpl::BrowserThreadImpl(BrowserThread::ID identifier,
|
| MessageLoop* message_loop)
|
| - : Thread(message_loop->thread_name().c_str()),
|
| - identifier_(identifier) {
|
| - set_message_loop(message_loop);
|
| - Initialize();
|
| + : BrowserThread(identifier, message_loop) {
|
| }
|
|
|
| -void BrowserThreadImpl::Init() {
|
| - using base::subtle::AtomicWord;
|
| - AtomicWord* storage =
|
| - reinterpret_cast<AtomicWord*>(&g_browser_thread_delegates[identifier_]);
|
| - AtomicWord stored_pointer = base::subtle::NoBarrier_Load(storage);
|
| - BrowserThreadDelegate* delegate =
|
| - reinterpret_cast<BrowserThreadDelegate*>(stored_pointer);
|
| - if (delegate)
|
| - delegate->Init();
|
| -}
|
| -
|
| -void BrowserThreadImpl::CleanUp() {
|
| - using base::subtle::AtomicWord;
|
| - AtomicWord* storage =
|
| - reinterpret_cast<AtomicWord*>(&g_browser_thread_delegates[identifier_]);
|
| - AtomicWord stored_pointer = base::subtle::NoBarrier_Load(storage);
|
| - BrowserThreadDelegate* delegate =
|
| - reinterpret_cast<BrowserThreadDelegate*>(stored_pointer);
|
| -
|
| - if (delegate)
|
| - delegate->CleanUp();
|
| -}
|
| -
|
| -void BrowserThreadImpl::Initialize() {
|
| - base::AutoLock lock(g_lock.Get());
|
| - DCHECK(identifier_ >= 0 && identifier_ < ID_COUNT);
|
| - DCHECK(g_browser_threads[identifier_] == NULL);
|
| - g_browser_threads[identifier_] = this;
|
| -}
|
| -
|
| BrowserThreadImpl::~BrowserThreadImpl() {
|
| - // All Thread subclasses must call Stop() in the destructor. This is
|
| - // doubly important here as various bits of code check they are on
|
| - // the right BrowserThread.
|
| Stop();
|
| -
|
| - base::AutoLock lock(g_lock.Get());
|
| - g_browser_threads[identifier_] = NULL;
|
| -#ifndef NDEBUG
|
| - // Double check that the threads are ordered correctly in the enumeration.
|
| - for (int i = identifier_ + 1; i < ID_COUNT; ++i) {
|
| - DCHECK(!g_browser_threads[i]) <<
|
| - "Threads must be listed in the reverse order that they die";
|
| - }
|
| -#endif
|
| }
|
|
|
| // static
|
| @@ -128,7 +77,7 @@
|
| BrowserThread::ID current_thread;
|
| bool guaranteed_to_outlive_target_thread =
|
| GetCurrentThreadIdentifier(¤t_thread) &&
|
| - current_thread <= identifier;
|
| + current_thread >= identifier;
|
|
|
| if (!guaranteed_to_outlive_target_thread)
|
| g_lock.Get().Acquire();
|
| @@ -169,7 +118,7 @@
|
| BrowserThread::ID current_thread;
|
| bool guaranteed_to_outlive_target_thread =
|
| GetCurrentThreadIdentifier(¤t_thread) &&
|
| - current_thread <= identifier;
|
| + current_thread >= identifier;
|
|
|
| if (!guaranteed_to_outlive_target_thread)
|
| g_lock.Get().Acquire();
|
| @@ -190,6 +139,18 @@
|
| return !!message_loop;
|
| }
|
|
|
| +// TODO(joi): Remove
|
| +DeprecatedBrowserThread::DeprecatedBrowserThread(BrowserThread::ID identifier)
|
| + : BrowserThread(identifier) {
|
| +}
|
| +DeprecatedBrowserThread::DeprecatedBrowserThread(BrowserThread::ID identifier,
|
| + MessageLoop* message_loop)
|
| + : BrowserThread(identifier, message_loop) {
|
| +}
|
| +DeprecatedBrowserThread::~DeprecatedBrowserThread() {
|
| + Stop();
|
| +}
|
| +
|
| // An implementation of MessageLoopProxy to be used in conjunction
|
| // with BrowserThread.
|
| class BrowserThreadMessageLoopProxy : public base::MessageLoopProxy {
|
| @@ -254,6 +215,44 @@
|
| DISALLOW_COPY_AND_ASSIGN(BrowserThreadMessageLoopProxy);
|
| };
|
|
|
| +BrowserThread::BrowserThread(ID identifier)
|
| + : Thread(browser_thread_names[identifier]),
|
| + identifier_(identifier) {
|
| + Initialize();
|
| +}
|
| +
|
| +BrowserThread::BrowserThread(ID identifier,
|
| + MessageLoop* message_loop)
|
| + : Thread(message_loop->thread_name().c_str()),
|
| + identifier_(identifier) {
|
| + set_message_loop(message_loop);
|
| + Initialize();
|
| +}
|
| +
|
| +void BrowserThread::Initialize() {
|
| + base::AutoLock lock(g_lock.Get());
|
| + DCHECK(identifier_ >= 0 && identifier_ < ID_COUNT);
|
| + DCHECK(g_browser_threads[identifier_] == NULL);
|
| + g_browser_threads[identifier_] = this;
|
| +}
|
| +
|
| +BrowserThread::~BrowserThread() {
|
| + // Stop the thread here, instead of the parent's class destructor. This is so
|
| + // that if there are pending tasks that run, code that checks that it's on the
|
| + // correct BrowserThread succeeds.
|
| + Stop();
|
| +
|
| + base::AutoLock lock(g_lock.Get());
|
| + g_browser_threads[identifier_] = NULL;
|
| +#ifndef NDEBUG
|
| + // Double check that the threads are ordered correctly in the enumeration.
|
| + for (int i = identifier_ + 1; i < ID_COUNT; ++i) {
|
| + DCHECK(!g_browser_threads[i]) <<
|
| + "Threads must be listed in the reverse order that they die";
|
| + }
|
| +#endif
|
| +}
|
| +
|
| // static
|
| bool BrowserThread::IsWellKnownThread(ID identifier) {
|
| base::AutoLock lock(g_lock.Get());
|
| @@ -394,23 +393,4 @@
|
| return proxy;
|
| }
|
|
|
| -base::Thread* BrowserThread::UnsafeGetBrowserThread(ID identifier) {
|
| - base::AutoLock lock(g_lock.Get());
|
| - base::Thread* thread = g_browser_threads[identifier];
|
| - DCHECK(thread);
|
| - return thread;
|
| -}
|
| -
|
| -void BrowserThread::SetDelegate(ID identifier,
|
| - BrowserThreadDelegate* delegate) {
|
| - using base::subtle::AtomicWord;
|
| - AtomicWord* storage = reinterpret_cast<AtomicWord*>(
|
| - &g_browser_thread_delegates[identifier]);
|
| - AtomicWord old_pointer = base::subtle::NoBarrier_AtomicExchange(
|
| - storage, reinterpret_cast<AtomicWord>(delegate));
|
| -
|
| - // This catches registration when previously registered.
|
| - DCHECK(!delegate || !old_pointer);
|
| -}
|
| -
|
| } // namespace content
|
|
|