diff options
author | jam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-27 03:59:31 +0000 |
---|---|---|
committer | jam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-27 03:59:31 +0000 |
commit | d85cf074f2186dbe1cf8a9db5d89a2b817ffb0e1 (patch) | |
tree | e03156e3142955f7cf637fe404a1ce2c6f7aaaf4 /chrome/browser/chrome_thread.h | |
parent | 76a188be4e3ddc42c42beabfeeeb618b2adae11e (diff) | |
download | chromium_src-d85cf074f2186dbe1cf8a9db5d89a2b817ffb0e1.zip chromium_src-d85cf074f2186dbe1cf8a9db5d89a2b817ffb0e1.tar.gz chromium_src-d85cf074f2186dbe1cf8a9db5d89a2b817ffb0e1.tar.bz2 |
Simplify threading in browser thread by making only ChromeThread deal with different thread lifetimes.The rest of the code doesn't get MessageLoop pointers since they're not thread-safe and instead just call PostTask on ChromeThread. If the target thread is not alive, then the task is simply deleted.In a followup change, I'll remove any remaining MessageLoop* caching. With this change, there's little to be gained by caching since no locks are involved if the target MessageLoop is guaranteed to outlive the current thread (inferred automatically by the order of the chrome_threads_ array).BUG=25354
Review URL: http://codereview.chromium.org/306032
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@30163 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/chrome_thread.h')
-rw-r--r-- | chrome/browser/chrome_thread.h | 103 |
1 files changed, 74 insertions, 29 deletions
diff --git a/chrome/browser/chrome_thread.h b/chrome/browser/chrome_thread.h index 28e308f..c135d34 100644 --- a/chrome/browser/chrome_thread.h +++ b/chrome/browser/chrome_thread.h @@ -1,11 +1,12 @@ -// 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. -#ifndef CHROME_BROWSER_CHROME_THREAD_H__ -#define CHROME_BROWSER_CHROME_THREAD_H__ +#ifndef CHROME_BROWSER_CHROME_THREAD_H_ +#define CHROME_BROWSER_CHROME_THREAD_H_ #include "base/lock.h" +#include "base/task.h" #include "base/thread.h" /////////////////////////////////////////////////////////////////////////////// @@ -14,30 +15,29 @@ // This class represents a thread that is known by a browser-wide name. For // example, there is one IO thread for the entire browser process, and various // pieces of code find it useful to retrieve a pointer to the IO thread's -// MessageLoop by name: +// Invoke a task by thread ID: // -// MessageLoop* io_loop = ChromeThread::GetMessageLoop(ChromeThread::IO); +// ChromeThread::PostTask(ChromeThread::IO, FROM_HERE, task); // -// On the UI thread, it is often preferable to obtain a pointer to a well-known -// thread via the g_browser_process object, e.g. g_browser_process->io_thread(); -// -// Code that runs on a thread other than the UI thread must take extra care in -// handling pointers to threads because many of the well-known threads are owned -// by the UI thread and can be deallocated without notice. +// The return value is false if the task couldn't be posted because the target +// thread doesn't exist. If this could lead to data loss, you need to check the +// result and restructure the code to ensure it doesn't occur. // +// This class automatically handles the lifetime of different threads. +// It's always safe to call PostTask on any thread. If it's not yet created, +// the task is deleted. There are no race conditions. If the thread that the +// task is posted to is guaranteed to outlive the current thread, then no locks +// are used. You should never need to cache pointers to MessageLoops, since +// they're not thread safe. class ChromeThread : public base::Thread { public: // An enumeration of the well-known threads. + // NOTE: threads must be listed in the order of their life-time, with each + // thread outliving every other thread below it. enum ID { // The main thread in the browser. UI, - // This is the thread that processes IPC and network messages. - IO, - - // This is the thread that interacts with the file system. - FILE, - // This is the thread that interacts with the database. DB, @@ -45,6 +45,12 @@ class ChromeThread : public base::Thread { // NOT in --single-process mode. WEBKIT, + // This is the thread that interacts with the file system. + FILE, + + // This is the thread that processes IPC and network messages. + IO, + #if defined(OS_LINUX) // This thread has a second connection to the X server and is used to // process UI requests when routing the request to the UI thread would risk @@ -62,20 +68,48 @@ class ChromeThread : public base::Thread { // to construct a ChromeThread that already exists. explicit ChromeThread(ID identifier); - // Special constructor for the main (UI) thread. We use a dummy thread here - // since the main thread already exists. - ChromeThread(); + // Special constructor for the main (UI) thread and unittests. We use a dummy + // thread here since the main thread already exists. + ChromeThread(ID identifier, MessageLoop* message_loop); virtual ~ChromeThread(); - // Callable on any thread, this helper function returns a pointer to the - // thread's MessageLoop. - // - // WARNING: - // Nothing in this class prevents the MessageLoop object returned from this - // function from being destroyed on another thread. Use with care. - // - static MessageLoop* GetMessageLoop(ID identifier); + // These are the same methods in message_loop.h, but are guaranteed to either + // get posted to the MessageLoop if it's still alive, or be deleted otherwise. + // They return true iff the thread existed and the task was posted. Note that + // even if the task is posted, there's no guarantee that it will run, since + // the target thread may already have a Quit message in its queue. + static bool PostTask(ID identifier, + const tracked_objects::Location& from_here, + Task* task); + static bool PostDelayedTask(ID identifier, + const tracked_objects::Location& from_here, + Task* task, + int64 delay_ms); + static bool PostNonNestableTask(ID identifier, + const tracked_objects::Location& from_here, + Task* task); + static bool PostNonNestableDelayedTask( + ID identifier, + const tracked_objects::Location& from_here, + Task* task, + int64 delay_ms); + + template <class T> + static bool DeleteSoon(ID identifier, + const tracked_objects::Location& from_here, + T* object) { + return PostNonNestableTask( + identifier, from_here, new DeleteTask<T>(object)); + } + + template <class T> + static bool ReleaseSoon(ID identifier, + const tracked_objects::Location& from_here, + T* object) { + return PostNonNestableTask( + identifier, from_here, new ReleaseTask<T>(object)); + } // Callable on any thread. Returns whether you're currently on a particular // thread. @@ -91,6 +125,17 @@ class ChromeThread : public base::Thread { // Common initialization code for the constructors. void Initialize(); + // If the current message loop is one of the known threads, returns true and + // sets identifier to its ID. Otherwise returns false. + static bool GetCurrentThreadIdentifier(ID* identifier); + + static bool PostTaskHelper( + ID identifier, + const tracked_objects::Location& from_here, + Task* task, + int64 delay_ms, + bool nestable); + // The identifier of this thread. Only one thread can exist with a given // identifier at a given time. ID identifier_; @@ -106,4 +151,4 @@ class ChromeThread : public base::Thread { static ChromeThread* chrome_threads_[ID_COUNT]; }; -#endif // #ifndef CHROME_BROWSER_CHROME_THREAD_H__ +#endif // #ifndef CHROME_BROWSER_CHROME_THREAD_H_ |