OLD | NEW |
---|---|
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef CHROME_BROWSER_CHROME_THREAD_H__ | 5 #ifndef CHROME_BROWSER_CHROME_THREAD_H_ |
6 #define CHROME_BROWSER_CHROME_THREAD_H__ | 6 #define CHROME_BROWSER_CHROME_THREAD_H_ |
7 | 7 |
8 #include "base/lock.h" | 8 #include "base/lock.h" |
9 #include "base/task.h" | |
9 #include "base/thread.h" | 10 #include "base/thread.h" |
10 | 11 |
11 /////////////////////////////////////////////////////////////////////////////// | 12 /////////////////////////////////////////////////////////////////////////////// |
12 // ChromeThread | 13 // ChromeThread |
13 // | 14 // |
14 // This class represents a thread that is known by a browser-wide name. For | 15 // This class represents a thread that is known by a browser-wide name. For |
15 // example, there is one IO thread for the entire browser process, and various | 16 // example, there is one IO thread for the entire browser process, and various |
16 // pieces of code find it useful to retrieve a pointer to the IO thread's | 17 // pieces of code find it useful to retrieve a pointer to the IO thread's |
17 // MessageLoop by name: | 18 // Invoke a task by thread ID: |
18 // | 19 // |
19 // MessageLoop* io_loop = ChromeThread::GetMessageLoop(ChromeThread::IO); | 20 // ChromeThread::PostTask(ChromeThread::IO, FROM_HERE, task); |
20 // | 21 // |
21 // On the UI thread, it is often preferable to obtain a pointer to a well-known | 22 // The return value is false if the task couldn't be posted because the target |
22 // thread via the g_browser_process object, e.g. g_browser_process->io_thread(); | 23 // thread doesn't exist. If this could lead to data loss, you need to check the |
24 // result and restructure the code to ensure it doesn't occur. | |
23 // | 25 // |
24 // Code that runs on a thread other than the UI thread must take extra care in | 26 // This class automatically handles the lifetime of different threads. |
25 // handling pointers to threads because many of the well-known threads are owned | 27 // It's always safe to call PostTask on any thread. If it's not yet created, |
26 // by the UI thread and can be deallocated without notice. | 28 // the task is deleted. There are no race conditions. If the thread that the |
27 // | 29 // task is posted to is guaranteed to outlive the current thread, then no locks |
30 // are used. You should never need to cache pointers to MessageLoops, since | |
31 // they're not thread safe. | |
28 class ChromeThread : public base::Thread { | 32 class ChromeThread : public base::Thread { |
29 public: | 33 public: |
30 // An enumeration of the well-known threads. | 34 // An enumeration of the well-known threads. |
35 // NOTE: threads must be listed in the order of their life-time, with each | |
36 // thread outliving every other thread below it. | |
31 enum ID { | 37 enum ID { |
darin (slow to review)
2009/10/27 00:06:52
maybe we should have an identifier named CURRENT,
jam
2009/10/27 02:38:18
Wouldn't this be a little confusing, since in the
darin (slow to review)
2009/10/27 04:43:33
True, good point.
This sort of makes me wish that
| |
32 // The main thread in the browser. | 38 // The main thread in the browser. |
33 UI, | 39 UI, |
34 | 40 |
35 // This is the thread that processes IPC and network messages. | |
36 IO, | |
37 | |
38 // This is the thread that interacts with the file system. | |
39 FILE, | |
40 | |
41 // This is the thread that interacts with the database. | 41 // This is the thread that interacts with the database. |
42 DB, | 42 DB, |
43 | 43 |
44 // This is the "main" thread for WebKit within the browser process when | 44 // This is the "main" thread for WebKit within the browser process when |
45 // NOT in --single-process mode. | 45 // NOT in --single-process mode. |
46 WEBKIT, | 46 WEBKIT, |
47 | 47 |
48 // This is the thread that interacts with the file system. | |
49 FILE, | |
50 | |
51 // This is the thread that processes IPC and network messages. | |
52 IO, | |
53 | |
48 #if defined(OS_LINUX) | 54 #if defined(OS_LINUX) |
49 // This thread has a second connection to the X server and is used to | 55 // This thread has a second connection to the X server and is used to |
50 // process UI requests when routing the request to the UI thread would risk | 56 // process UI requests when routing the request to the UI thread would risk |
51 // deadlock. | 57 // deadlock. |
52 BACKGROUND_X11, | 58 BACKGROUND_X11, |
53 #endif | 59 #endif |
54 | 60 |
55 // This identifier does not represent a thread. Instead it counts the | 61 // This identifier does not represent a thread. Instead it counts the |
56 // number of well-known threads. Insert new well-known threads before this | 62 // number of well-known threads. Insert new well-known threads before this |
57 // identifier. | 63 // identifier. |
58 ID_COUNT | 64 ID_COUNT |
59 }; | 65 }; |
60 | 66 |
61 // Construct a ChromeThread with the supplied identifier. It is an error | 67 // Construct a ChromeThread with the supplied identifier. It is an error |
62 // to construct a ChromeThread that already exists. | 68 // to construct a ChromeThread that already exists. |
63 explicit ChromeThread(ID identifier); | 69 explicit ChromeThread(ID identifier); |
64 | 70 |
65 // Special constructor for the main (UI) thread. We use a dummy thread here | 71 // Special constructor for the main (UI) thread and unittests. We use a dummy |
66 // since the main thread already exists. | 72 // thread here since the main thread already exists. |
67 ChromeThread(); | 73 ChromeThread(ID identifier, MessageLoop* message_loop); |
68 | 74 |
69 virtual ~ChromeThread(); | 75 virtual ~ChromeThread(); |
70 | 76 |
71 // Callable on any thread, this helper function returns a pointer to the | 77 // These are the same methods in message_loop.h, but are guaranteed to either |
72 // thread's MessageLoop. | 78 // get posted to the MessageLoop if it's still alive, or be deleted otherwise. |
73 // | 79 // They return true iff the thread existed and the task was posted. |
darin (slow to review)
2009/10/27 00:06:52
you should probably add a note here indicating tha
jam
2009/10/27 02:38:18
Done.
darin (slow to review)
2009/10/27 04:43:33
OK
| |
74 // WARNING: | 80 static bool PostTask(ID identifier, |
75 // Nothing in this class prevents the MessageLoop object returned from this | 81 const tracked_objects::Location& from_here, |
76 // function from being destroyed on another thread. Use with care. | 82 Task* task); |
77 // | 83 static bool PostDelayedTask(ID identifier, |
78 static MessageLoop* GetMessageLoop(ID identifier); | 84 const tracked_objects::Location& from_here, |
85 Task* task, | |
86 int64 delay_ms); | |
87 static bool PostNonNestableTask(ID identifier, | |
88 const tracked_objects::Location& from_here, | |
89 Task* task); | |
90 static bool PostNonNestableDelayedTask( | |
91 ID identifier, | |
92 const tracked_objects::Location& from_here, | |
93 Task* task, | |
94 int64 delay_ms); | |
95 | |
96 template <class T> | |
97 static bool DeleteSoon(ID identifier, | |
98 const tracked_objects::Location& from_here, | |
99 T* object) { | |
100 return PostNonNestableTask( | |
101 identifier, from_here, new DeleteTask<T>(object)); | |
102 } | |
103 | |
104 template <class T> | |
105 static bool ReleaseSoon(ID identifier, | |
106 const tracked_objects::Location& from_here, | |
107 T* object) { | |
108 return PostNonNestableTask( | |
109 identifier, from_here, new ReleaseTask<T>(object)); | |
110 } | |
79 | 111 |
80 // Callable on any thread. Returns whether you're currently on a particular | 112 // Callable on any thread. Returns whether you're currently on a particular |
81 // thread. | 113 // thread. |
82 // | 114 // |
83 // WARNING: | 115 // WARNING: |
84 // When running under unit-tests, this will return true if you're on the | 116 // When running under unit-tests, this will return true if you're on the |
85 // main thread and the thread ID you pass in isn't running. This is | 117 // main thread and the thread ID you pass in isn't running. This is |
86 // normally the correct behavior because you want to ignore these asserts | 118 // normally the correct behavior because you want to ignore these asserts |
87 // unless you've specifically spun up the threads, but be mindful of it. | 119 // unless you've specifically spun up the threads, but be mindful of it. |
88 static bool CurrentlyOn(ID identifier); | 120 static bool CurrentlyOn(ID identifier); |
89 | 121 |
90 private: | 122 private: |
91 // Common initialization code for the constructors. | 123 // Common initialization code for the constructors. |
92 void Initialize(); | 124 void Initialize(); |
93 | 125 |
126 // If the current message loop is one of the known threads, returns true and | |
127 // sets identifier to its ID. Otherwise returns false. | |
128 static bool GetCurrentThreadIdentifier(ID* identifier); | |
129 | |
130 static bool PostTaskHelper( | |
131 ID identifier, | |
132 const tracked_objects::Location& from_here, | |
133 Task* task, | |
134 int64 delay_ms, | |
135 bool nestable); | |
136 | |
94 // The identifier of this thread. Only one thread can exist with a given | 137 // The identifier of this thread. Only one thread can exist with a given |
95 // identifier at a given time. | 138 // identifier at a given time. |
96 ID identifier_; | 139 ID identifier_; |
97 | 140 |
98 // This lock protects |chrome_threads_|. Do not read or modify that array | 141 // This lock protects |chrome_threads_|. Do not read or modify that array |
99 // without holding this lock. Do not block while holding this lock. | 142 // without holding this lock. Do not block while holding this lock. |
100 static Lock lock_; | 143 static Lock lock_; |
101 | 144 |
102 // An array of the ChromeThread objects. This array is protected by |lock_|. | 145 // An array of the ChromeThread objects. This array is protected by |lock_|. |
103 // The threads are not owned by this array. Typically, the threads are owned | 146 // The threads are not owned by this array. Typically, the threads are owned |
104 // on the UI thread by the g_browser_process object. ChromeThreads remove | 147 // on the UI thread by the g_browser_process object. ChromeThreads remove |
105 // themselves from this array upon destruction. | 148 // themselves from this array upon destruction. |
106 static ChromeThread* chrome_threads_[ID_COUNT]; | 149 static ChromeThread* chrome_threads_[ID_COUNT]; |
107 }; | 150 }; |
108 | 151 |
109 #endif // #ifndef CHROME_BROWSER_CHROME_THREAD_H__ | 152 #endif // #ifndef CHROME_BROWSER_CHROME_THREAD_H_ |
OLD | NEW |