| 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 13 matching lines...) Expand all Loading... |
| 24 static const char* g_browser_thread_names[BrowserThread::ID_COUNT] = { | 24 static const char* g_browser_thread_names[BrowserThread::ID_COUNT] = { |
| 25 "", // UI (name assembled in browser_main.cc). | 25 "", // UI (name assembled in browser_main.cc). |
| 26 "Chrome_DBThread", // DB | 26 "Chrome_DBThread", // DB |
| 27 "Chrome_FileThread", // FILE | 27 "Chrome_FileThread", // FILE |
| 28 "Chrome_FileUserBlockingThread", // FILE_USER_BLOCKING | 28 "Chrome_FileUserBlockingThread", // FILE_USER_BLOCKING |
| 29 "Chrome_ProcessLauncherThread", // PROCESS_LAUNCHER | 29 "Chrome_ProcessLauncherThread", // PROCESS_LAUNCHER |
| 30 "Chrome_CacheThread", // CACHE | 30 "Chrome_CacheThread", // CACHE |
| 31 "Chrome_IOThread", // IO | 31 "Chrome_IOThread", // IO |
| 32 }; | 32 }; |
| 33 | 33 |
| 34 // An implementation of MessageLoopProxy to be used in conjunction |
| 35 // with BrowserThread. |
| 36 class BrowserThreadMessageLoopProxy : public base::MessageLoopProxy { |
| 37 public: |
| 38 explicit BrowserThreadMessageLoopProxy(BrowserThread::ID identifier) |
| 39 : id_(identifier) { |
| 40 } |
| 41 |
| 42 // MessageLoopProxy implementation. |
| 43 virtual bool PostDelayedTask( |
| 44 const tracked_objects::Location& from_here, |
| 45 const base::Closure& task, base::TimeDelta delay) OVERRIDE { |
| 46 return BrowserThread::PostDelayedTask(id_, from_here, task, delay); |
| 47 } |
| 48 |
| 49 virtual bool PostNonNestableDelayedTask( |
| 50 const tracked_objects::Location& from_here, |
| 51 const base::Closure& task, |
| 52 base::TimeDelta delay) OVERRIDE { |
| 53 return BrowserThread::PostNonNestableDelayedTask(id_, from_here, task, |
| 54 delay); |
| 55 } |
| 56 |
| 57 virtual bool RunsTasksOnCurrentThread() const OVERRIDE { |
| 58 return BrowserThread::CurrentlyOn(id_); |
| 59 } |
| 60 |
| 61 protected: |
| 62 virtual ~BrowserThreadMessageLoopProxy() {} |
| 63 |
| 64 private: |
| 65 BrowserThread::ID id_; |
| 66 DISALLOW_COPY_AND_ASSIGN(BrowserThreadMessageLoopProxy); |
| 67 }; |
| 68 |
| 69 // A separate helper is used just for the proxies, in order to avoid needing |
| 70 // to initialize the globals to create a proxy. |
| 71 struct BrowserThreadProxies { |
| 72 BrowserThreadProxies() { |
| 73 for (int i = 0; i < BrowserThread::ID_COUNT; ++i) { |
| 74 proxies[i] = |
| 75 new BrowserThreadMessageLoopProxy(static_cast<BrowserThread::ID>(i)); |
| 76 } |
| 77 } |
| 78 |
| 79 scoped_refptr<base::MessageLoopProxy> proxies[BrowserThread::ID_COUNT]; |
| 80 }; |
| 81 |
| 82 base::LazyInstance<BrowserThreadProxies>::Leaky |
| 83 g_proxies = LAZY_INSTANCE_INITIALIZER; |
| 84 |
| 34 struct BrowserThreadGlobals { | 85 struct BrowserThreadGlobals { |
| 35 BrowserThreadGlobals() | 86 BrowserThreadGlobals() |
| 36 : blocking_pool(new base::SequencedWorkerPool(3, "BrowserBlocking")) { | 87 : blocking_pool(new base::SequencedWorkerPool(3, "BrowserBlocking")) { |
| 37 memset(threads, 0, BrowserThread::ID_COUNT * sizeof(threads[0])); | 88 memset(threads, 0, BrowserThread::ID_COUNT * sizeof(threads[0])); |
| 38 memset(thread_delegates, 0, | 89 memset(thread_delegates, 0, |
| 39 BrowserThread::ID_COUNT * sizeof(thread_delegates[0])); | 90 BrowserThread::ID_COUNT * sizeof(thread_delegates[0])); |
| 40 } | 91 } |
| 41 | 92 |
| 42 // This lock protects |threads|. Do not read or modify that array | 93 // This lock protects |threads|. Do not read or modify that array |
| 43 // without holding this lock. Do not block while holding this lock. | 94 // without holding this lock. Do not block while holding this lock. |
| (...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 267 message_loop->PostNonNestableDelayedTask(from_here, task, delay); | 318 message_loop->PostNonNestableDelayedTask(from_here, task, delay); |
| 268 } | 319 } |
| 269 } | 320 } |
| 270 | 321 |
| 271 if (!target_thread_outlives_current) | 322 if (!target_thread_outlives_current) |
| 272 globals.lock.Release(); | 323 globals.lock.Release(); |
| 273 | 324 |
| 274 return !!message_loop; | 325 return !!message_loop; |
| 275 } | 326 } |
| 276 | 327 |
| 277 // An implementation of MessageLoopProxy to be used in conjunction | |
| 278 // with BrowserThread. | |
| 279 class BrowserThreadMessageLoopProxy : public base::MessageLoopProxy { | |
| 280 public: | |
| 281 explicit BrowserThreadMessageLoopProxy(BrowserThread::ID identifier) | |
| 282 : id_(identifier) { | |
| 283 } | |
| 284 | |
| 285 // MessageLoopProxy implementation. | |
| 286 virtual bool PostDelayedTask( | |
| 287 const tracked_objects::Location& from_here, | |
| 288 const base::Closure& task, base::TimeDelta delay) OVERRIDE { | |
| 289 return BrowserThread::PostDelayedTask(id_, from_here, task, delay); | |
| 290 } | |
| 291 | |
| 292 virtual bool PostNonNestableDelayedTask( | |
| 293 const tracked_objects::Location& from_here, | |
| 294 const base::Closure& task, | |
| 295 base::TimeDelta delay) OVERRIDE { | |
| 296 return BrowserThread::PostNonNestableDelayedTask(id_, from_here, task, | |
| 297 delay); | |
| 298 } | |
| 299 | |
| 300 virtual bool RunsTasksOnCurrentThread() const OVERRIDE { | |
| 301 return BrowserThread::CurrentlyOn(id_); | |
| 302 } | |
| 303 | |
| 304 protected: | |
| 305 virtual ~BrowserThreadMessageLoopProxy() {} | |
| 306 | |
| 307 private: | |
| 308 BrowserThread::ID id_; | |
| 309 DISALLOW_COPY_AND_ASSIGN(BrowserThreadMessageLoopProxy); | |
| 310 }; | |
| 311 | |
| 312 // static | 328 // static |
| 313 bool BrowserThread::PostBlockingPoolTask( | 329 bool BrowserThread::PostBlockingPoolTask( |
| 314 const tracked_objects::Location& from_here, | 330 const tracked_objects::Location& from_here, |
| 315 const base::Closure& task) { | 331 const base::Closure& task) { |
| 316 return g_globals.Get().blocking_pool->PostWorkerTask(from_here, task); | 332 return g_globals.Get().blocking_pool->PostWorkerTask(from_here, task); |
| 317 } | 333 } |
| 318 | 334 |
| 319 // static | 335 // static |
| 320 bool BrowserThread::PostBlockingPoolTaskAndReply( | 336 bool BrowserThread::PostBlockingPoolTaskAndReply( |
| 321 const tracked_objects::Location& from_here, | 337 const tracked_objects::Location& from_here, |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 470 return true; | 486 return true; |
| 471 } | 487 } |
| 472 } | 488 } |
| 473 | 489 |
| 474 return false; | 490 return false; |
| 475 } | 491 } |
| 476 | 492 |
| 477 // static | 493 // static |
| 478 scoped_refptr<base::MessageLoopProxy> | 494 scoped_refptr<base::MessageLoopProxy> |
| 479 BrowserThread::GetMessageLoopProxyForThread(ID identifier) { | 495 BrowserThread::GetMessageLoopProxyForThread(ID identifier) { |
| 480 return make_scoped_refptr(new BrowserThreadMessageLoopProxy(identifier)); | 496 return g_proxies.Get().proxies[identifier]; |
| 481 } | 497 } |
| 482 | 498 |
| 483 // static | 499 // static |
| 484 base::MessageLoop* BrowserThread::UnsafeGetMessageLoopForThread(ID identifier) { | 500 base::MessageLoop* BrowserThread::UnsafeGetMessageLoopForThread(ID identifier) { |
| 485 if (g_globals == NULL) | 501 if (g_globals == NULL) |
| 486 return NULL; | 502 return NULL; |
| 487 | 503 |
| 488 BrowserThreadGlobals& globals = g_globals.Get(); | 504 BrowserThreadGlobals& globals = g_globals.Get(); |
| 489 base::AutoLock lock(globals.lock); | 505 base::AutoLock lock(globals.lock); |
| 490 base::Thread* thread = globals.threads[identifier]; | 506 base::Thread* thread = globals.threads[identifier]; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 501 AtomicWord* storage = reinterpret_cast<AtomicWord*>( | 517 AtomicWord* storage = reinterpret_cast<AtomicWord*>( |
| 502 &globals.thread_delegates[identifier]); | 518 &globals.thread_delegates[identifier]); |
| 503 AtomicWord old_pointer = base::subtle::NoBarrier_AtomicExchange( | 519 AtomicWord old_pointer = base::subtle::NoBarrier_AtomicExchange( |
| 504 storage, reinterpret_cast<AtomicWord>(delegate)); | 520 storage, reinterpret_cast<AtomicWord>(delegate)); |
| 505 | 521 |
| 506 // This catches registration when previously registered. | 522 // This catches registration when previously registered. |
| 507 DCHECK(!delegate || !old_pointer); | 523 DCHECK(!delegate || !old_pointer); |
| 508 } | 524 } |
| 509 | 525 |
| 510 } // namespace content | 526 } // namespace content |
| OLD | NEW |