| Index: content/browser/browser_thread_impl.cc
|
| diff --git a/content/browser/browser_thread_impl.cc b/content/browser/browser_thread_impl.cc
|
| index 274acc39afe3e6f445b29aa6c29b74026b06461b..cc5b9d00428c06c64e89675609321535fbc0e121 100644
|
| --- a/content/browser/browser_thread_impl.cc
|
| +++ b/content/browser/browser_thread_impl.cc
|
| @@ -106,14 +106,19 @@ struct BrowserThreadGlobals {
|
| "BrowserBlocking",
|
| base::TaskPriority::USER_VISIBLE)) {
|
| memset(threads, 0, BrowserThread::ID_COUNT * sizeof(threads[0]));
|
| + memset(thread_ids, 0, BrowserThread::ID_COUNT * sizeof(thread_ids[0]));
|
| memset(thread_delegates, 0,
|
| BrowserThread::ID_COUNT * sizeof(thread_delegates[0]));
|
| }
|
|
|
| - // This lock protects |threads|. Do not read or modify that array
|
| - // without holding this lock. Do not block while holding this lock.
|
| + // This lock protects |threads| and |thread_ids|. Do not read or modify those
|
| + // arrays without holding this lock. Do not block while holding this lock.
|
| base::Lock lock;
|
|
|
| + // This array is protected by |lock|. IDs in this array are populated as soon
|
| + // as their respective thread is started and are never reset.
|
| + base::PlatformThreadId thread_ids[BrowserThread::ID_COUNT];
|
| +
|
| // This array is protected by |lock|. The threads are not owned by this
|
| // array. Typically, the threads are owned on the UI thread by
|
| // BrowserMainLoop. BrowserThreadImpl objects remove themselves from this
|
| @@ -135,6 +140,13 @@ base::LazyInstance<BrowserThreadGlobals>::Leaky
|
| BrowserThreadImpl::BrowserThreadImpl(ID identifier)
|
| : Thread(GetThreadName(identifier)), identifier_(identifier) {
|
| Initialize();
|
| +
|
| + // Unit tests may create multiple TestBrowserThreadBundles, causing the same
|
| + // BrowserThread ID to be reinitialized. We explicitly clear the thread ID
|
| + // here so Start() can sanity check.
|
| + BrowserThreadGlobals& globals = g_globals.Get();
|
| + base::AutoLock lock(globals.lock);
|
| + globals.thread_ids[identifier] = base::kInvalidThreadId;
|
| }
|
|
|
| BrowserThreadImpl::BrowserThreadImpl(ID identifier,
|
| @@ -142,6 +154,12 @@ BrowserThreadImpl::BrowserThreadImpl(ID identifier,
|
| : Thread(GetThreadName(identifier)), identifier_(identifier) {
|
| set_message_loop(message_loop);
|
| Initialize();
|
| +
|
| + // If constructed with an explicit message loop, this is a fake BrowserThread
|
| + // which runs on the current thread.
|
| + BrowserThreadGlobals& globals = g_globals.Get();
|
| + base::AutoLock lock(globals.lock);
|
| + globals.thread_ids[identifier] = base::PlatformThread::CurrentId();
|
| }
|
|
|
| // static
|
| @@ -317,15 +335,28 @@ BrowserThreadImpl::~BrowserThreadImpl() {
|
| #endif
|
| }
|
|
|
| +bool BrowserThreadImpl::Start() {
|
| + return StartWithOptions(base::Thread::Options());
|
| +}
|
| +
|
| bool BrowserThreadImpl::StartWithOptions(const Options& options) {
|
| // The global thread table needs to be locked while a new thread is
|
| // starting, as the new thread can asynchronously start touching the
|
| // table (and other thread's message_loop).
|
| BrowserThreadGlobals& globals = g_globals.Get();
|
| base::AutoLock lock(globals.lock);
|
| - return Thread::StartWithOptions(options);
|
| + DCHECK_EQ(globals.thread_ids[identifier_], base::kInvalidThreadId);
|
| + bool result = Thread::StartWithOptions(options);
|
| + globals.thread_ids[identifier_] = GetThreadId();
|
| + return result;
|
| }
|
|
|
| +bool BrowserThreadImpl::StartAndWaitForTesting() {
|
| + if (!Start())
|
| + return false;
|
| + WaitUntilThreadStarted();
|
| + return true;
|
| +}
|
| // static
|
| bool BrowserThreadImpl::PostTaskHelper(
|
| BrowserThread::ID identifier,
|
| @@ -425,9 +456,7 @@ bool BrowserThread::CurrentlyOn(ID identifier) {
|
| base::AutoLock lock(globals.lock);
|
| DCHECK_GE(identifier, 0);
|
| DCHECK_LT(identifier, ID_COUNT);
|
| - return globals.threads[identifier] &&
|
| - globals.threads[identifier]->message_loop() ==
|
| - base::MessageLoop::current();
|
| + return base::PlatformThread::CurrentId() == globals.thread_ids[identifier];
|
| }
|
|
|
| // static
|
|
|