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" |
11 #include "base/compiler_specific.h" | 11 #include "base/compiler_specific.h" |
12 #include "base/lazy_instance.h" | 12 #include "base/lazy_instance.h" |
13 #include "base/single_thread_task_runner.h" | 13 #include "base/message_loop/message_loop.h" |
| 14 #include "base/message_loop/message_loop_proxy.h" |
14 #include "base/threading/sequenced_worker_pool.h" | 15 #include "base/threading/sequenced_worker_pool.h" |
15 #include "base/threading/thread_restrictions.h" | 16 #include "base/threading/thread_restrictions.h" |
16 #include "content/public/browser/browser_thread_delegate.h" | 17 #include "content/public/browser/browser_thread_delegate.h" |
17 #include "content/public/browser/content_browser_client.h" | 18 #include "content/public/browser/content_browser_client.h" |
18 #include "net/disk_cache/simple/simple_backend_impl.h" | 19 #include "net/disk_cache/simple/simple_backend_impl.h" |
19 | 20 |
20 #if defined(OS_ANDROID) | 21 #if defined(OS_ANDROID) |
21 #include "base/android/jni_android.h" | 22 #include "base/android/jni_android.h" |
22 #endif | 23 #endif |
23 | 24 |
24 namespace content { | 25 namespace content { |
25 | 26 |
26 namespace { | 27 namespace { |
27 | 28 |
28 // Friendly names for the well-known threads. | 29 // Friendly names for the well-known threads. |
29 static const char* g_browser_thread_names[BrowserThread::ID_COUNT] = { | 30 static const char* g_browser_thread_names[BrowserThread::ID_COUNT] = { |
30 "", // UI (name assembled in browser_main.cc). | 31 "", // UI (name assembled in browser_main.cc). |
31 "Chrome_DBThread", // DB | 32 "Chrome_DBThread", // DB |
32 "Chrome_FileThread", // FILE | 33 "Chrome_FileThread", // FILE |
33 "Chrome_FileUserBlockingThread", // FILE_USER_BLOCKING | 34 "Chrome_FileUserBlockingThread", // FILE_USER_BLOCKING |
34 "Chrome_ProcessLauncherThread", // PROCESS_LAUNCHER | 35 "Chrome_ProcessLauncherThread", // PROCESS_LAUNCHER |
35 "Chrome_CacheThread", // CACHE | 36 "Chrome_CacheThread", // CACHE |
36 "Chrome_IOThread", // IO | 37 "Chrome_IOThread", // IO |
37 }; | 38 }; |
38 | 39 |
39 // An implementation of SingleThreadTaskRunner to be used in conjunction | 40 // An implementation of MessageLoopProxy to be used in conjunction |
40 // with BrowserThread. | 41 // with BrowserThread. |
41 class BrowserThreadTaskRunner : public base::SingleThreadTaskRunner { | 42 class BrowserThreadMessageLoopProxy : public base::MessageLoopProxy { |
42 public: | 43 public: |
43 explicit BrowserThreadTaskRunner(BrowserThread::ID identifier) | 44 explicit BrowserThreadMessageLoopProxy(BrowserThread::ID identifier) |
44 : id_(identifier) {} | 45 : id_(identifier) { |
| 46 } |
45 | 47 |
46 // SingleThreadTaskRunner implementation. | 48 // MessageLoopProxy implementation. |
47 bool PostDelayedTask(const tracked_objects::Location& from_here, | 49 bool PostDelayedTask(const tracked_objects::Location& from_here, |
48 const base::Closure& task, | 50 const base::Closure& task, |
49 base::TimeDelta delay) override { | 51 base::TimeDelta delay) override { |
50 return BrowserThread::PostDelayedTask(id_, from_here, task, delay); | 52 return BrowserThread::PostDelayedTask(id_, from_here, task, delay); |
51 } | 53 } |
52 | 54 |
53 bool PostNonNestableDelayedTask(const tracked_objects::Location& from_here, | 55 bool PostNonNestableDelayedTask(const tracked_objects::Location& from_here, |
54 const base::Closure& task, | 56 const base::Closure& task, |
55 base::TimeDelta delay) override { | 57 base::TimeDelta delay) override { |
56 return BrowserThread::PostNonNestableDelayedTask(id_, from_here, task, | 58 return BrowserThread::PostNonNestableDelayedTask(id_, from_here, task, |
57 delay); | 59 delay); |
58 } | 60 } |
59 | 61 |
60 bool RunsTasksOnCurrentThread() const override { | 62 bool RunsTasksOnCurrentThread() const override { |
61 return BrowserThread::CurrentlyOn(id_); | 63 return BrowserThread::CurrentlyOn(id_); |
62 } | 64 } |
63 | 65 |
64 protected: | 66 protected: |
65 ~BrowserThreadTaskRunner() override {} | 67 ~BrowserThreadMessageLoopProxy() override {} |
66 | 68 |
67 private: | 69 private: |
68 BrowserThread::ID id_; | 70 BrowserThread::ID id_; |
69 DISALLOW_COPY_AND_ASSIGN(BrowserThreadTaskRunner); | 71 DISALLOW_COPY_AND_ASSIGN(BrowserThreadMessageLoopProxy); |
70 }; | 72 }; |
71 | 73 |
72 // A separate helper is used just for the task runners, in order to avoid | 74 // A separate helper is used just for the proxies, in order to avoid needing |
73 // needing to initialize the globals to create a task runner. | 75 // to initialize the globals to create a proxy. |
74 struct BrowserThreadTaskRunners { | 76 struct BrowserThreadProxies { |
75 BrowserThreadTaskRunners() { | 77 BrowserThreadProxies() { |
76 for (int i = 0; i < BrowserThread::ID_COUNT; ++i) { | 78 for (int i = 0; i < BrowserThread::ID_COUNT; ++i) { |
77 proxies[i] = | 79 proxies[i] = |
78 new BrowserThreadTaskRunner(static_cast<BrowserThread::ID>(i)); | 80 new BrowserThreadMessageLoopProxy(static_cast<BrowserThread::ID>(i)); |
79 } | 81 } |
80 } | 82 } |
81 | 83 |
82 scoped_refptr<base::SingleThreadTaskRunner> proxies[BrowserThread::ID_COUNT]; | 84 scoped_refptr<base::MessageLoopProxy> proxies[BrowserThread::ID_COUNT]; |
83 }; | 85 }; |
84 | 86 |
85 base::LazyInstance<BrowserThreadTaskRunners>::Leaky g_task_runners = | 87 base::LazyInstance<BrowserThreadProxies>::Leaky |
86 LAZY_INSTANCE_INITIALIZER; | 88 g_proxies = LAZY_INSTANCE_INITIALIZER; |
87 | 89 |
88 struct BrowserThreadGlobals { | 90 struct BrowserThreadGlobals { |
89 BrowserThreadGlobals() | 91 BrowserThreadGlobals() |
90 : blocking_pool(new base::SequencedWorkerPool(3, "BrowserBlocking")) { | 92 : blocking_pool(new base::SequencedWorkerPool(3, "BrowserBlocking")) { |
91 memset(threads, 0, BrowserThread::ID_COUNT * sizeof(threads[0])); | 93 memset(threads, 0, BrowserThread::ID_COUNT * sizeof(threads[0])); |
92 memset(thread_delegates, 0, | 94 memset(thread_delegates, 0, |
93 BrowserThread::ID_COUNT * sizeof(thread_delegates[0])); | 95 BrowserThread::ID_COUNT * sizeof(thread_delegates[0])); |
94 } | 96 } |
95 | 97 |
96 // This lock protects |threads|. Do not read or modify that array | 98 // This lock protects |threads|. Do not read or modify that array |
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
322 | 324 |
323 BrowserThreadGlobals& globals = g_globals.Get(); | 325 BrowserThreadGlobals& globals = g_globals.Get(); |
324 if (!target_thread_outlives_current) | 326 if (!target_thread_outlives_current) |
325 globals.lock.Acquire(); | 327 globals.lock.Acquire(); |
326 | 328 |
327 base::MessageLoop* message_loop = | 329 base::MessageLoop* message_loop = |
328 globals.threads[identifier] ? globals.threads[identifier]->message_loop() | 330 globals.threads[identifier] ? globals.threads[identifier]->message_loop() |
329 : NULL; | 331 : NULL; |
330 if (message_loop) { | 332 if (message_loop) { |
331 if (nestable) { | 333 if (nestable) { |
332 message_loop->task_runner()->PostDelayedTask(from_here, task, delay); | 334 message_loop->PostDelayedTask(from_here, task, delay); |
333 } else { | 335 } else { |
334 message_loop->task_runner()->PostNonNestableDelayedTask(from_here, task, | 336 message_loop->PostNonNestableDelayedTask(from_here, task, delay); |
335 delay); | |
336 } | 337 } |
337 } | 338 } |
338 | 339 |
339 if (!target_thread_outlives_current) | 340 if (!target_thread_outlives_current) |
340 globals.lock.Release(); | 341 globals.lock.Release(); |
341 | 342 |
342 return !!message_loop; | 343 return !!message_loop; |
343 } | 344 } |
344 | 345 |
345 // static | 346 // static |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
509 globals.threads[i]->message_loop() == cur_message_loop) { | 510 globals.threads[i]->message_loop() == cur_message_loop) { |
510 *identifier = globals.threads[i]->identifier_; | 511 *identifier = globals.threads[i]->identifier_; |
511 return true; | 512 return true; |
512 } | 513 } |
513 } | 514 } |
514 | 515 |
515 return false; | 516 return false; |
516 } | 517 } |
517 | 518 |
518 // static | 519 // static |
519 scoped_refptr<base::SingleThreadTaskRunner> | 520 scoped_refptr<base::MessageLoopProxy> |
520 BrowserThread::GetMessageLoopProxyForThread(ID identifier) { | 521 BrowserThread::GetMessageLoopProxyForThread(ID identifier) { |
521 return g_task_runners.Get().proxies[identifier]; | 522 return g_proxies.Get().proxies[identifier]; |
522 } | 523 } |
523 | 524 |
524 // static | 525 // static |
525 base::MessageLoop* BrowserThread::UnsafeGetMessageLoopForThread(ID identifier) { | 526 base::MessageLoop* BrowserThread::UnsafeGetMessageLoopForThread(ID identifier) { |
526 if (g_globals == NULL) | 527 if (g_globals == NULL) |
527 return NULL; | 528 return NULL; |
528 | 529 |
529 BrowserThreadGlobals& globals = g_globals.Get(); | 530 BrowserThreadGlobals& globals = g_globals.Get(); |
530 base::AutoLock lock(globals.lock); | 531 base::AutoLock lock(globals.lock); |
531 base::Thread* thread = globals.threads[identifier]; | 532 base::Thread* thread = globals.threads[identifier]; |
(...skipping 10 matching lines...) Expand all Loading... |
542 AtomicWord* storage = reinterpret_cast<AtomicWord*>( | 543 AtomicWord* storage = reinterpret_cast<AtomicWord*>( |
543 &globals.thread_delegates[identifier]); | 544 &globals.thread_delegates[identifier]); |
544 AtomicWord old_pointer = base::subtle::NoBarrier_AtomicExchange( | 545 AtomicWord old_pointer = base::subtle::NoBarrier_AtomicExchange( |
545 storage, reinterpret_cast<AtomicWord>(delegate)); | 546 storage, reinterpret_cast<AtomicWord>(delegate)); |
546 | 547 |
547 // This catches registration when previously registered. | 548 // This catches registration when previously registered. |
548 DCHECK(!delegate || !old_pointer); | 549 DCHECK(!delegate || !old_pointer); |
549 } | 550 } |
550 | 551 |
551 } // namespace content | 552 } // namespace content |
OLD | NEW |