diff options
Diffstat (limited to 'chrome/browser/chrome_thread.cc')
-rw-r--r-- | chrome/browser/chrome_thread.cc | 129 |
1 files changed, 101 insertions, 28 deletions
diff --git a/chrome/browser/chrome_thread.cc b/chrome/browser/chrome_thread.cc index 8cd7767..576ac77 100644 --- a/chrome/browser/chrome_thread.cc +++ b/chrome/browser/chrome_thread.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2009 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -7,10 +7,10 @@ // Friendly names for the well-known threads. static const char* chrome_thread_names[ChromeThread::ID_COUNT] = { "", // UI (name assembled in browser_main.cc). - "Chrome_IOThread", // IO - "Chrome_FileThread", // FILE "Chrome_DBThread", // DB "Chrome_WebKitThread", // WEBKIT + "Chrome_FileThread", // FILE + "Chrome_IOThread", // IO #if defined(OS_LINUX) "Chrome_Background_X11Thread", // BACKGROUND_X11 #endif @@ -18,16 +18,7 @@ static const char* chrome_thread_names[ChromeThread::ID_COUNT] = { Lock ChromeThread::lock_; -ChromeThread* ChromeThread::chrome_threads_[ID_COUNT] = { - NULL, // UI - NULL, // IO - NULL, // FILE - NULL, // DB - NULL, // WEBKIT -#if defined(OS_LINUX) - NULL, // BACKGROUND_X11 -#endif -}; +ChromeThread* ChromeThread::chrome_threads_[ID_COUNT]; ChromeThread::ChromeThread(ChromeThread::ID identifier) : Thread(chrome_thread_names[identifier]), @@ -35,10 +26,10 @@ ChromeThread::ChromeThread(ChromeThread::ID identifier) Initialize(); } -ChromeThread::ChromeThread() - : Thread(MessageLoop::current()->thread_name().c_str()), - identifier_(UI) { - set_message_loop(MessageLoop::current()); +ChromeThread::ChromeThread(ID identifier, MessageLoop* message_loop) + : Thread(message_loop->thread_name().c_str()), + identifier_(identifier) { + set_message_loop(message_loop); Initialize(); } @@ -52,26 +43,108 @@ void ChromeThread::Initialize() { ChromeThread::~ChromeThread() { AutoLock lock(lock_); chrome_threads_[identifier_] = NULL; +#ifndef NDEBUG + // Double check that the threads are ordererd correctly in the enumeration. + for (int i = identifier_ + 1; i < ID_COUNT; ++i) { + DCHECK(!chrome_threads_[i]) << + "Threads must be listed in the reverse order that they die"; + } +#endif } // static -MessageLoop* ChromeThread::GetMessageLoop(ID identifier) { +bool ChromeThread::CurrentlyOn(ID identifier) { + // chrome_threads_[identifier] will be NULL if none is running. This is often + // true when running under unit tests. This behavior actually works out + // pretty conveniently but it's worth noting here. AutoLock lock(lock_); DCHECK(identifier >= 0 && identifier < ID_COUNT); + return chrome_threads_[identifier] && + chrome_threads_[identifier]->message_loop() == MessageLoop::current(); +} - if (chrome_threads_[identifier]) - return chrome_threads_[identifier]->message_loop(); +// static +bool ChromeThread::PostTask(ID identifier, + const tracked_objects::Location& from_here, + Task* task) { + return PostTaskHelper(identifier, from_here, task, 0, true); +} - return NULL; +// static +bool ChromeThread::PostDelayedTask(ID identifier, + const tracked_objects::Location& from_here, + Task* task, + int64 delay_ms) { + return PostTaskHelper(identifier, from_here, task, delay_ms, true); } // static -bool ChromeThread::CurrentlyOn(ID identifier) { - // MessageLoop::current() will return NULL if none is running. This is often - // true when running under unit tests. This behavior actually works out - // pretty convienently (as is mentioned in the header file comment), but it's - // worth noting here. - MessageLoop* message_loop = GetMessageLoop(identifier); - return MessageLoop::current() == message_loop; +bool ChromeThread::PostNonNestableTask( + ID identifier, + const tracked_objects::Location& from_here, + Task* task) { + return PostTaskHelper(identifier, from_here, task, 0, false); +} + +// static +bool ChromeThread::PostNonNestableDelayedTask( + ID identifier, + const tracked_objects::Location& from_here, + Task* task, + int64 delay_ms) { + return PostTaskHelper(identifier, from_here, task, delay_ms, false); +} + +// static +bool ChromeThread::GetCurrentThreadIdentifier(ID* identifier) { + MessageLoop* cur_message_loop = MessageLoop::current(); + for (int i = 0; i < ID_COUNT; ++i) { + if (chrome_threads_[i] && + chrome_threads_[i]->message_loop() == cur_message_loop) { + *identifier = chrome_threads_[i]->identifier_; + return true; + } + } + + return false; } +// static +bool ChromeThread::PostTaskHelper( + ID identifier, + const tracked_objects::Location& from_here, + Task* task, + int64 delay_ms, + bool nestable) { + DCHECK(identifier >= 0 && identifier < ID_COUNT); + // Optimization: to avoid unnecessary locks, we listed the ID enumeration in + // order of lifetime. So no need to lock if we know that the other thread + // outlives this one. + // Note: since the array is so small, ok to loop instead of creating a map, + // which would require a lock because std::map isn't thread safe, defeating + // the whole purpose of this optimization. + ID current_thread; + bool guaranteed_to_outlive_target_thread = + GetCurrentThreadIdentifier(¤t_thread) && + current_thread >= identifier; + + if (!guaranteed_to_outlive_target_thread) + lock_.Acquire(); + + MessageLoop* message_loop = chrome_threads_[identifier] ? + chrome_threads_[identifier]->message_loop() : NULL; + if (message_loop) { + if (nestable) { + message_loop->PostDelayedTask(from_here, task, delay_ms); + } else { + message_loop->PostNonNestableDelayedTask(from_here, task, delay_ms); + } + } else { + delete task; + } + + if (!guaranteed_to_outlive_target_thread) + lock_.Release(); + + return !!message_loop; +} |