diff options
author | joi@chromium.org <joi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-11-28 14:00:36 +0000 |
---|---|---|
committer | joi@chromium.org <joi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-11-28 14:00:36 +0000 |
commit | 14f79fec5f13a623f837f0b9438556180e5e7896 (patch) | |
tree | f86cadba8422d4a453acc22792406ff2b2cb8da8 /content/browser/browser_thread_impl.cc | |
parent | f8a7f81d377eb872c2c9760813966920810edfb3 (diff) | |
download | chromium_src-14f79fec5f13a623f837f0b9438556180e5e7896.zip chromium_src-14f79fec5f13a623f837f0b9438556180e5e7896.tar.gz chromium_src-14f79fec5f13a623f837f0b9438556180e5e7896.tar.bz2 |
Revert 111695 - Have content/ create and destroy its own threads.
Reason: Problems on official builders.
Change embedding API and embedders to allow for this.
Push inheritance of base::Thread down to content::BrowserThreadImpl so
that content::BrowserThread is just a namespace for API functions.
This change temporarily disables chrome_frame_net_tests as agreed by the CF lead, see bug 105435.
TBR=ben@chromium.org (IWYU change only)
BUG=98716,104578,105435
Review URL: http://codereview.chromium.org/8477004
TBR=joi@chromium.org
Review URL: http://codereview.chromium.org/8718012
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@111698 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content/browser/browser_thread_impl.cc')
-rw-r--r-- | content/browser/browser_thread_impl.cc | 160 |
1 files changed, 70 insertions, 90 deletions
diff --git a/content/browser/browser_thread_impl.cc b/content/browser/browser_thread_impl.cc index 0025f77..023259b 100644 --- a/content/browser/browser_thread_impl.cc +++ b/content/browser/browser_thread_impl.cc @@ -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 @@ static const char* g_browser_thread_names[BrowserThread::ID_COUNT] = { #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 -// themselves from this array upon destruction. -static BrowserThreadImpl* 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]; +// 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. +BrowserThread* g_browser_threads[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(); -} - -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; + : BrowserThread(identifier, message_loop) { } 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 @@ bool BrowserThreadImpl::PostTaskHelper( 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 @@ bool BrowserThreadImpl::PostTaskHelper( 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 @@ bool BrowserThreadImpl::PostTaskHelper( 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 @@ class BrowserThreadMessageLoopProxy : public base::MessageLoopProxy { 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 @@ BrowserThread::GetMessageLoopProxyForThread( 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 |