OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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_impl.h" | 5 #include "content/browser/browser_thread_impl.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/atomicops.h" | 9 #include "base/atomicops.h" |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
231 base::TimeDelta delay, | 231 base::TimeDelta delay, |
232 bool nestable) { | 232 bool nestable) { |
233 DCHECK(identifier >= 0 && identifier < ID_COUNT); | 233 DCHECK(identifier >= 0 && identifier < ID_COUNT); |
234 // Optimization: to avoid unnecessary locks, we listed the ID enumeration in | 234 // Optimization: to avoid unnecessary locks, we listed the ID enumeration in |
235 // order of lifetime. So no need to lock if we know that the other thread | 235 // order of lifetime. So no need to lock if we know that the other thread |
236 // outlives this one. | 236 // outlives this one. |
237 // Note: since the array is so small, ok to loop instead of creating a map, | 237 // Note: since the array is so small, ok to loop instead of creating a map, |
238 // which would require a lock because std::map isn't thread safe, defeating | 238 // which would require a lock because std::map isn't thread safe, defeating |
239 // the whole purpose of this optimization. | 239 // the whole purpose of this optimization. |
240 BrowserThread::ID current_thread; | 240 BrowserThread::ID current_thread; |
241 bool guaranteed_to_outlive_target_thread = | 241 bool target_thread_outlives_current = |
242 GetCurrentThreadIdentifier(¤t_thread) && | 242 GetCurrentThreadIdentifier(¤t_thread) && |
243 current_thread <= identifier; | 243 current_thread >= identifier; |
244 | 244 |
245 BrowserThreadGlobals& globals = g_globals.Get(); | 245 BrowserThreadGlobals& globals = g_globals.Get(); |
246 if (!guaranteed_to_outlive_target_thread) | 246 if (!target_thread_outlives_current) |
247 globals.lock.Acquire(); | 247 globals.lock.Acquire(); |
248 | 248 |
249 MessageLoop* message_loop = globals.threads[identifier] ? | 249 MessageLoop* message_loop = globals.threads[identifier] ? |
250 globals.threads[identifier]->message_loop() : NULL; | 250 globals.threads[identifier]->message_loop() : NULL; |
251 if (message_loop) { | 251 if (message_loop) { |
252 if (nestable) { | 252 if (nestable) { |
253 message_loop->PostDelayedTask(from_here, task, delay); | 253 message_loop->PostDelayedTask(from_here, task, delay); |
254 } else { | 254 } else { |
255 message_loop->PostNonNestableDelayedTask(from_here, task, delay); | 255 message_loop->PostNonNestableDelayedTask(from_here, task, delay); |
256 } | 256 } |
257 } | 257 } |
258 | 258 |
259 if (!guaranteed_to_outlive_target_thread) | 259 if (!target_thread_outlives_current) |
260 globals.lock.Release(); | 260 globals.lock.Release(); |
261 | 261 |
262 return !!message_loop; | 262 return !!message_loop; |
263 } | 263 } |
264 | 264 |
265 // An implementation of MessageLoopProxy to be used in conjunction | 265 // An implementation of MessageLoopProxy to be used in conjunction |
266 // with BrowserThread. | 266 // with BrowserThread. |
267 class BrowserThreadMessageLoopProxy : public base::MessageLoopProxy { | 267 class BrowserThreadMessageLoopProxy : public base::MessageLoopProxy { |
268 public: | 268 public: |
269 explicit BrowserThreadMessageLoopProxy(BrowserThread::ID identifier) | 269 explicit BrowserThreadMessageLoopProxy(BrowserThread::ID identifier) |
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
463 AtomicWord* storage = reinterpret_cast<AtomicWord*>( | 463 AtomicWord* storage = reinterpret_cast<AtomicWord*>( |
464 &globals.thread_delegates[identifier]); | 464 &globals.thread_delegates[identifier]); |
465 AtomicWord old_pointer = base::subtle::NoBarrier_AtomicExchange( | 465 AtomicWord old_pointer = base::subtle::NoBarrier_AtomicExchange( |
466 storage, reinterpret_cast<AtomicWord>(delegate)); | 466 storage, reinterpret_cast<AtomicWord>(delegate)); |
467 | 467 |
468 // This catches registration when previously registered. | 468 // This catches registration when previously registered. |
469 DCHECK(!delegate || !old_pointer); | 469 DCHECK(!delegate || !old_pointer); |
470 } | 470 } |
471 | 471 |
472 } // namespace content | 472 } // namespace content |
OLD | NEW |