Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(223)

Side by Side Diff: chrome/browser/chrome_thread.cc

Issue 306032: Simplify threading in browser thread by making only ChromeThread deal with di... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: a few more simplifications Created 11 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 #include "chrome/browser/chrome_thread.h" 5 #include "chrome/browser/chrome_thread.h"
6 6
7 // Friendly names for the well-known threads. 7 // Friendly names for the well-known threads.
8 static const char* chrome_thread_names[ChromeThread::ID_COUNT] = { 8 static const char* chrome_thread_names[ChromeThread::ID_COUNT] = {
9 "", // UI (name assembled in browser_main.cc). 9 "", // UI (name assembled in browser_main.cc).
10 "Chrome_IOThread", // IO
11 "Chrome_FileThread", // FILE
12 "Chrome_DBThread", // DB 10 "Chrome_DBThread", // DB
13 "Chrome_WebKitThread", // WEBKIT 11 "Chrome_WebKitThread", // WEBKIT
12 "Chrome_FileThread", // FILE
13 "Chrome_IOThread", // IO
14 #if defined(OS_LINUX) 14 #if defined(OS_LINUX)
15 "Chrome_Background_X11Thread", // BACKGROUND_X11 15 "Chrome_Background_X11Thread", // BACKGROUND_X11
16 #endif 16 #endif
17 }; 17 };
18 18
19 Lock ChromeThread::lock_; 19 Lock ChromeThread::lock_;
20 20
21 ChromeThread* ChromeThread::chrome_threads_[ID_COUNT] = { 21 ChromeThread* ChromeThread::chrome_threads_[ID_COUNT];
22 NULL, // UI
23 NULL, // IO
24 NULL, // FILE
25 NULL, // DB
26 NULL, // WEBKIT
27 #if defined(OS_LINUX)
28 NULL, // BACKGROUND_X11
29 #endif
30 };
31 22
32 ChromeThread::ChromeThread(ChromeThread::ID identifier) 23 ChromeThread::ChromeThread(ChromeThread::ID identifier)
33 : Thread(chrome_thread_names[identifier]), 24 : Thread(chrome_thread_names[identifier]),
34 identifier_(identifier) { 25 identifier_(identifier) {
35 Initialize(); 26 Initialize();
36 } 27 }
37 28
38 ChromeThread::ChromeThread() 29 ChromeThread::ChromeThread(ID identifier, MessageLoop* message_loop)
39 : Thread(MessageLoop::current()->thread_name().c_str()), 30 : Thread(message_loop->thread_name().c_str()),
40 identifier_(UI) { 31 identifier_(identifier) {
41 set_message_loop(MessageLoop::current()); 32 set_message_loop(message_loop);
42 Initialize(); 33 Initialize();
43 } 34 }
44 35
45 void ChromeThread::Initialize() { 36 void ChromeThread::Initialize() {
46 AutoLock lock(lock_); 37 AutoLock lock(lock_);
47 DCHECK(identifier_ >= 0 && identifier_ < ID_COUNT); 38 DCHECK(identifier_ >= 0 && identifier_ < ID_COUNT);
48 DCHECK(chrome_threads_[identifier_] == NULL); 39 DCHECK(chrome_threads_[identifier_] == NULL);
49 chrome_threads_[identifier_] = this; 40 chrome_threads_[identifier_] = this;
50 } 41 }
51 42
52 ChromeThread::~ChromeThread() { 43 ChromeThread::~ChromeThread() {
53 AutoLock lock(lock_); 44 AutoLock lock(lock_);
54 chrome_threads_[identifier_] = NULL; 45 chrome_threads_[identifier_] = NULL;
55 } 46 #ifndef NDEBUG
56 47 // Double check that the threads are ordererd correctly in the enumeration.
57 // static 48 for (int i = identifier_ + 1; i < ID_COUNT; ++i) {
58 MessageLoop* ChromeThread::GetMessageLoop(ID identifier) { 49 DCHECK(!chrome_threads_[i]) <<
59 AutoLock lock(lock_); 50 "Threads must be listed in the reverse order that they die";
60 DCHECK(identifier >= 0 && identifier < ID_COUNT); 51 }
61 52 #endif
62 if (chrome_threads_[identifier])
63 return chrome_threads_[identifier]->message_loop();
64
65 return NULL;
66 } 53 }
67 54
68 // static 55 // static
69 bool ChromeThread::CurrentlyOn(ID identifier) { 56 bool ChromeThread::CurrentlyOn(ID identifier) {
70 // MessageLoop::current() will return NULL if none is running. This is often 57 // chrome_threads_[identifier] will be NULL if none is running. This is often
71 // true when running under unit tests. This behavior actually works out 58 // true when running under unit tests. This behavior actually works out
72 // pretty convienently (as is mentioned in the header file comment), but it's 59 // pretty conveniently but it's worth noting here.
73 // worth noting here. 60 AutoLock lock(lock_);
74 MessageLoop* message_loop = GetMessageLoop(identifier); 61 DCHECK(identifier >= 0 && identifier < ID_COUNT);
75 return MessageLoop::current() == message_loop; 62 return chrome_threads_[identifier] &&
63 chrome_threads_[identifier]->message_loop() == MessageLoop::current();
76 } 64 }
77 65
66 // static
67 bool ChromeThread::PostTask(ID identifier,
68 const tracked_objects::Location& from_here,
69 Task* task) {
70 return PostTaskHelper(identifier, from_here, task, 0, true);
71 }
72
73 // static
74 bool ChromeThread::PostDelayedTask(ID identifier,
75 const tracked_objects::Location& from_here,
76 Task* task,
77 int64 delay_ms) {
78 return PostTaskHelper(identifier, from_here, task, delay_ms, true);
79 }
80
81 // static
82 bool ChromeThread::PostNonNestableTask(
83 ID identifier,
84 const tracked_objects::Location& from_here,
85 Task* task) {
86 return PostTaskHelper(identifier, from_here, task, 0, false);
87 }
88
89 // static
90 bool ChromeThread::PostNonNestableDelayedTask(
91 ID identifier,
92 const tracked_objects::Location& from_here,
93 Task* task,
94 int64 delay_ms) {
95 return PostTaskHelper(identifier, from_here, task, delay_ms, false);
96 }
97
98 // static
99 bool ChromeThread::GetCurrentThreadIdentifier(ID* identifier) {
100 MessageLoop* cur_message_loop = MessageLoop::current();
101 for (int i = 0; i < ID_COUNT; ++i) {
102 if (chrome_threads_[i] &&
103 chrome_threads_[i]->message_loop() == cur_message_loop) {
104 *identifier = chrome_threads_[i]->identifier_;
105 return true;
106 }
107 }
108
109 return false;
110 }
111
112 // static
113 bool ChromeThread::PostTaskHelper(
114 ID identifier,
115 const tracked_objects::Location& from_here,
116 Task* task,
117 int64 delay_ms,
118 bool nestable) {
119 DCHECK(identifier >= 0 && identifier < ID_COUNT);
120 // Optimization: to avoid unnecessary locks, we listed the ID enumeration in
121 // order of lifetime. So no need to lock if we know that the other thread
122 // outlives this one.
123 // Note: since the array is so small, ok to loop instead of creating a map,
124 // which would require a lock because std::map isn't thread safe, defeating
125 // the whole purpose of this optimization.
126 ID current_thread;
127 bool guaranteed_to_outlive_target_thread =
128 GetCurrentThreadIdentifier(&current_thread) &&
129 current_thread >= identifier;
130
131 if (!guaranteed_to_outlive_target_thread)
132 lock_.Acquire();
133
134 MessageLoop* message_loop = chrome_threads_[identifier] ?
135 chrome_threads_[identifier]->message_loop() : NULL;
136 if (message_loop) {
137 if (nestable) {
138 message_loop->PostDelayedTask(from_here, task, delay_ms);
139 } else {
140 message_loop->PostNonNestableDelayedTask(from_here, task, delay_ms);
141 }
142 } else {
143 delete task;
darin (slow to review) 2009/10/27 00:06:52 maybe this should have a DLOG(INFO)? or would tha
jam 2009/10/27 02:38:18 I don't know how spammy it would be so I'm hesitan
darin (slow to review) 2009/10/27 04:43:33 True... I think we'll likely end up with some valg
144 }
145
146 if (!guaranteed_to_outlive_target_thread)
147 lock_.Release();
148
149 return !!message_loop;
150 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698