OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "content/browser/browser_thread.h" | 5 #include "content/browser/browser_thread.h" |
6 | 6 |
7 #include "base/message_loop.h" | 7 #include "base/message_loop.h" |
8 #include "base/message_loop_proxy.h" | 8 #include "base/message_loop_proxy.h" |
9 #include "base/threading/thread_restrictions.h" | 9 #include "base/threading/thread_restrictions.h" |
10 | 10 |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
132 bool BrowserThread::IsMessageLoopValid(ID identifier) { | 132 bool BrowserThread::IsMessageLoopValid(ID identifier) { |
133 base::AutoLock lock(lock_); | 133 base::AutoLock lock(lock_); |
134 DCHECK(identifier >= 0 && identifier < ID_COUNT); | 134 DCHECK(identifier >= 0 && identifier < ID_COUNT); |
135 return browser_threads_[identifier] && | 135 return browser_threads_[identifier] && |
136 browser_threads_[identifier]->message_loop(); | 136 browser_threads_[identifier]->message_loop(); |
137 } | 137 } |
138 | 138 |
139 // static | 139 // static |
140 bool BrowserThread::PostTask(ID identifier, | 140 bool BrowserThread::PostTask(ID identifier, |
141 const tracked_objects::Location& from_here, | 141 const tracked_objects::Location& from_here, |
| 142 const base::Closure& task) { |
| 143 return PostTaskHelper(identifier, from_here, task, 0, true); |
| 144 } |
| 145 |
| 146 // static |
| 147 bool BrowserThread::PostDelayedTask(ID identifier, |
| 148 const tracked_objects::Location& from_here, |
| 149 const base::Closure& task, |
| 150 int64 delay_ms) { |
| 151 return PostTaskHelper(identifier, from_here, task, delay_ms, true); |
| 152 } |
| 153 |
| 154 // static |
| 155 bool BrowserThread::PostNonNestableTask( |
| 156 ID identifier, |
| 157 const tracked_objects::Location& from_here, |
| 158 const base::Closure& task) { |
| 159 return PostTaskHelper(identifier, from_here, task, 0, false); |
| 160 } |
| 161 |
| 162 // static |
| 163 bool BrowserThread::PostNonNestableDelayedTask( |
| 164 ID identifier, |
| 165 const tracked_objects::Location& from_here, |
| 166 const base::Closure& task, |
| 167 int64 delay_ms) { |
| 168 return PostTaskHelper(identifier, from_here, task, delay_ms, false); |
| 169 } |
| 170 |
| 171 // static |
| 172 bool BrowserThread::PostTask(ID identifier, |
| 173 const tracked_objects::Location& from_here, |
142 Task* task) { | 174 Task* task) { |
143 return PostTaskHelper(identifier, from_here, task, 0, true); | 175 return PostTaskHelper(identifier, from_here, task, 0, true); |
144 } | 176 } |
145 | 177 |
146 // static | 178 // static |
147 bool BrowserThread::PostDelayedTask(ID identifier, | 179 bool BrowserThread::PostDelayedTask(ID identifier, |
148 const tracked_objects::Location& from_here, | 180 const tracked_objects::Location& from_here, |
149 Task* task, | 181 Task* task, |
150 int64 delay_ms) { | 182 int64 delay_ms) { |
151 return PostTaskHelper(identifier, from_here, task, delay_ms, true); | 183 return PostTaskHelper(identifier, from_here, task, delay_ms, true); |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
229 } | 261 } |
230 | 262 |
231 if (!guaranteed_to_outlive_target_thread) | 263 if (!guaranteed_to_outlive_target_thread) |
232 lock_.Release(); | 264 lock_.Release(); |
233 | 265 |
234 if (!message_loop) | 266 if (!message_loop) |
235 delete task; | 267 delete task; |
236 | 268 |
237 return !!message_loop; | 269 return !!message_loop; |
238 } | 270 } |
| 271 |
| 272 // static |
| 273 bool BrowserThread::PostTaskHelper( |
| 274 ID identifier, |
| 275 const tracked_objects::Location& from_here, |
| 276 const base::Closure& task, |
| 277 int64 delay_ms, |
| 278 bool nestable) { |
| 279 DCHECK(identifier >= 0 && identifier < ID_COUNT); |
| 280 // Optimization: to avoid unnecessary locks, we listed the ID enumeration in |
| 281 // order of lifetime. So no need to lock if we know that the other thread |
| 282 // outlives this one. |
| 283 // Note: since the array is so small, ok to loop instead of creating a map, |
| 284 // which would require a lock because std::map isn't thread safe, defeating |
| 285 // the whole purpose of this optimization. |
| 286 ID current_thread; |
| 287 bool guaranteed_to_outlive_target_thread = |
| 288 GetCurrentThreadIdentifier(¤t_thread) && |
| 289 current_thread >= identifier; |
| 290 |
| 291 if (!guaranteed_to_outlive_target_thread) |
| 292 lock_.Acquire(); |
| 293 |
| 294 MessageLoop* message_loop = browser_threads_[identifier] ? |
| 295 browser_threads_[identifier]->message_loop() : NULL; |
| 296 if (message_loop) { |
| 297 if (nestable) { |
| 298 message_loop->PostDelayedTask(from_here, task, delay_ms); |
| 299 } else { |
| 300 message_loop->PostNonNestableDelayedTask(from_here, task, delay_ms); |
| 301 } |
| 302 } |
| 303 |
| 304 if (!guaranteed_to_outlive_target_thread) |
| 305 lock_.Release(); |
| 306 |
| 307 return !!message_loop; |
| 308 } |
OLD | NEW |