summaryrefslogtreecommitdiffstats
path: root/content/browser/browser_thread_impl.cc
diff options
context:
space:
mode:
authorjoi@chromium.org <joi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-11-28 14:00:36 +0000
committerjoi@chromium.org <joi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-11-28 14:00:36 +0000
commit14f79fec5f13a623f837f0b9438556180e5e7896 (patch)
treef86cadba8422d4a453acc22792406ff2b2cb8da8 /content/browser/browser_thread_impl.cc
parentf8a7f81d377eb872c2c9760813966920810edfb3 (diff)
downloadchromium_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.cc160
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(&current_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(&current_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