Index: content/browser/browser_thread_impl.cc |
diff --git a/content/browser/browser_thread_impl.cc b/content/browser/browser_thread_impl.cc |
index b86643970e599c88c4bb044765f5e5d15ed0a160..dd77c8dac04a1d0175e768e2af5e333965f26f5b 100644 |
--- a/content/browser/browser_thread_impl.cc |
+++ b/content/browser/browser_thread_impl.cc |
@@ -13,9 +13,9 @@ |
#include "base/compiler_specific.h" |
#include "base/lazy_instance.h" |
#include "base/macros.h" |
+#include "base/profiler/scoped_tracker.h" |
#include "base/single_thread_task_runner.h" |
#include "base/threading/sequenced_worker_pool.h" |
-#include "base/threading/thread_restrictions.h" |
#include "build/build_config.h" |
#include "content/public/browser/browser_thread_delegate.h" |
#include "content/public/browser/content_browser_client.h" |
@@ -230,10 +230,11 @@ void BrowserThreadImpl::Run(base::MessageLoop* message_loop) { |
#endif |
BrowserThread::ID thread_id = ID_COUNT; |
- if (!GetCurrentThreadIdentifier(&thread_id)) |
- return Thread::Run(message_loop); |
+ CHECK(GetCurrentThreadIdentifier(&thread_id)); |
+ CHECK_EQ(identifier_, thread_id); |
+ CHECK_EQ(Thread::message_loop(), message_loop); |
- switch (thread_id) { |
+ switch (identifier_) { |
case BrowserThread::UI: |
return UIThreadRun(message_loop); |
case BrowserThread::DB: |
@@ -252,7 +253,10 @@ void BrowserThreadImpl::Run(base::MessageLoop* message_loop) { |
CHECK(false); // This shouldn't actually be reached! |
break; |
} |
- Thread::Run(message_loop); |
+ |
+ // |identifier_| must be set to a valid enum value in the constructor, so it |
+ // should be impossible to reach here. |
+ CHECK(false); |
} |
void BrowserThreadImpl::CleanUp() { |
@@ -267,6 +271,13 @@ void BrowserThreadImpl::CleanUp() { |
if (delegate) |
delegate->CleanUp(); |
+ |
+ // PostTaskHelper() accesses the message loop while holding this lock. |
+ // However, the message loop will soon be destructed without any locking. So |
+ // to prevent a race with accessing the message loop in PostTaskHelper(), |
+ // remove this thread from the global array now. |
+ base::AutoLock lock(globals.lock); |
+ globals.threads[identifier_] = NULL; |
} |
void BrowserThreadImpl::Initialize() { |
@@ -398,11 +409,6 @@ bool BrowserThread::IsThreadInitialized(ID identifier) { |
// static |
bool BrowserThread::CurrentlyOn(ID identifier) { |
- // We shouldn't use MessageLoop::current() since it uses LazyInstance which |
- // may be deleted by ~AtExitManager when a WorkerPool thread calls this |
- // function. |
- // http://crbug.com/63678 |
- base::ThreadRestrictions::ScopedAllowSingleton allow_singleton; |
BrowserThreadGlobals& globals = g_globals.Get(); |
base::AutoLock lock(globals.lock); |
DCHECK(identifier >= 0 && identifier < ID_COUNT); |
@@ -501,13 +507,13 @@ bool BrowserThread::GetCurrentThreadIdentifier(ID* identifier) { |
if (g_globals == NULL) |
return false; |
- // We shouldn't use MessageLoop::current() since it uses LazyInstance which |
- // may be deleted by ~AtExitManager when a WorkerPool thread calls this |
- // function. |
- // http://crbug.com/63678 |
- base::ThreadRestrictions::ScopedAllowSingleton allow_singleton; |
base::MessageLoop* cur_message_loop = base::MessageLoop::current(); |
BrowserThreadGlobals& globals = g_globals.Get(); |
+ // Profiler to track potential contention on |globals.lock|. This only does |
+ // real work on canary and local dev builds, so the cost of having this here |
+ // should be minimal. |
+ tracked_objects::ScopedTracker tracking_profile(FROM_HERE); |
+ base::AutoLock lock(globals.lock); |
for (int i = 0; i < ID_COUNT; ++i) { |
if (globals.threads[i] && |
globals.threads[i]->message_loop() == cur_message_loop) { |